[
  {
    "Id": "571262",
    "ThreadId": "247356",
    "Html": "<p>As per request, this is the official resurrection of the \"File in Use\"&nbsp;exception arising when working with MemoryStreams that have had XMLDocument .Save() on the stream explicitly.</p>\n<p>Previous report and example are in&nbsp;<a href=\"http://dotnetzip.codeplex.com/discussions/44663\">http://dotnetzip.codeplex.com/discussions/44663</a></p>\n<p>Notably, I can always reproduce this behavior, namely, unless I null the XMLDoc and call out GC.Collect the subsequent zip.Save() will always fail. I have tried staggering the thread (simulating \"old\" computer that seemed to work for previous poster), sleeping,  and even copying memory streams to no avail. XMLDocument has no IDisposable or Close implementations, so \"using\" is out the window.</p>\n<p>FYI,Windows7 + VS2010 Express C# with 4.0NETClient target. Also using latest available DotNetZip (reduced) assembly dll.</p>\n<p>Here is the code:</p>\n<p>\n<div style=\"color: black; background-color: white;\">\n<pre>MemoryStream stream_core = <span style=\"color: blue;\">new</span> MemoryStream();\nXmlDocument xmldoc_core = <span style=\"color: blue;\">new</span> XmlDocument();\n\n<span style=\"color: green;\">// We actually check if extracting worked in the working sample</span>\nZipEntry e_core = zip[<span style=\"color: #a31515;\">\"\\\\somepath\\\\somefile.xml\"</span>];\ne_core.Extract(stream_core);\nstream_core.Seek(0, SeekOrigin.Begin);\n\n<span style=\"color: green;\">// This is validated too</span>\nxmldoc_core.Load(stream_core);\n\n<span style=\"color: green;\">// This class function takes the xmldocument and modifies ut by appending some nodes, nothing fancy.</span>\nxmldoc_core = update_document(xmldoc_core, <span style=\"color: #a31515;\">\"1\"</span>, <span style=\"color: #a31515;\">\"2\"</span>, <span style=\"color: #a31515;\">\"3\"</span>, textBoxRevision.Text);\n<span style=\"color: green;\">// xmldoc is valid, commence pushback</span>\n\nMemoryStream stream_o_core = <span style=\"color: blue;\">new</span> MemoryStream();\n\n<span style=\"color: green;\">// save to another stream</span>\nxmldoc_core.Save(stream_o_core);\n\n<span style=\"color: green;\">// If this is uncommented, Saving works</span>\n<span style=\"color: green;\">// xmldoc_core = null;</span>\n<span style=\"color: green;\">// GC.Collect();</span>\n\n<span style=\"color: green;\">// Rewind</span>\nstream_o_core.Seek(0, SeekOrigin.Begin);\n\n<span style=\"color: green;\">// Remove and re-add</span>\nzip.RemoveEntry(<span style=\"color: #a31515;\">\"\\\\somepath\\\\somefile.xml\"</span>);\nzip.AddEntry(<span style=\"color: #a31515;\">\"\\\\somepath\\\\somefile.xml\"</span>, stream_o_core);\n\n<span style=\"color: green;\">// This will fail with IOException = sharing violation, file in use</span>\nzip.Save();\n</pre>\n</div>\n</p>\n<p>Please let me know what other details you need.</p>\n<p>Respectfully,</p>\n<p>K.</p>",
    "PostedDate": "2011-02-23T21:22:51.993-08:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "573430",
    "ThreadId": "247356",
    "Html": "<p>Hi kommi,</p>\r\n<p>I think the problem is that internally the XmlDocument.Save method wraps your stream in an Xml.XmlDOMWriter to perform the save, but it doesn't call Close / Dispose afterwards. I don't know if this is a bug, or whether it's by design, but it's probably what is causing the sharing violation by holding a reference to your stream_o_core until you kill the XmlDOMWriter&nbsp;with an explicit&nbsp;call to GC.Collect().</p>\r\n<p>It sounds like the garbage collector is probably more aggressive&nbsp;on slower machines (maybe because of less memory?) and calls GC.Collect() itself before the code gets to enter zip.Save().</p>\r\n<p>Hope this helps,</p>\r\n<p>Mike</p>",
    "PostedDate": "2011-02-28T11:45:31.12-08:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "573530",
    "ThreadId": "247356",
    "Html": "<p>Uhm, that would make sense, but what does .Save() of DotNetZip is actually doing to the MemoryStream to get the sharing violation? Should I instead explicitly instantiate an XMLWriter, write to stream, close the Writer and then pass the MemoryStream to DotNetZip? (XMLWriter does have a close)</p>",
    "PostedDate": "2011-02-28T14:30:51.667-08:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "573570",
    "ThreadId": "247356",
    "Html": "<p>Hi kommi,</p>\r\n<p>It's probably just trying to read data from the stream to zip it up, but if the XmlDocument it stream locked with \"Sharing = None\" then the zip object won't be able to read from it until the XmlDOMWriter is closed. I don't really have time at the moment to dig too deep into it at the moment, but you could try replicating the behaviour of XmlDocument.Save, and closing the XmlDOMWriter afterwards. Or you could copy the data from stream_o_core into a separate memorystream and pass that to DotNetZip.</p>\r\n<p>I can take another look if you can post a stack trace of the exception, but your best bet might just be to live with GC.Collect for now.</p>\r\n<p>Cheers,</p>\r\n<p>M</p>",
    "PostedDate": "2011-02-28T16:14:42.013-08:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "574017",
    "ThreadId": "247356",
    "Html": "<p>Ill try your suggestions, it's very hard to debug though: it happens sporadically, for example, right now I can not trigger the sharing violation to occur at all. Speaking of which, if stream is locked with no sharing, then I wouldn't be able to clone it either, no?</p>",
    "PostedDate": "2011-03-01T11:43:38.287-08:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "574059",
    "ThreadId": "247356",
    "Html": "<p>Possibly. I guess it depends on what locks XmlDOMWriter holds vs the ones DotNetZip wants. e.g.&nbsp;if DotNetZip wants Write even though it only needs Read then you might be able to get away with copying just using Read access. You might have to suck it and see...</p>\r\n<p>Implementing your own version of XmlDocument.Save is probably the \"best\" workaround. It's only half a dozen lines of code anyway.</p>\r\n<p>M</p>",
    "PostedDate": "2011-03-01T12:39:52.053-08:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "577805",
    "ThreadId": "247356",
    "Html": "<p>Seems to me you would want to try using the <a href=\"http://cheeso.members.winisp.net/DotNetZipHelp/html/633c4280-51ca-cc82-b5b5-86bbe9b2e947.htm\">ZipFile.AddEntry() method that accepts a WriteDelegate</a>.&nbsp;</p>\r\n<p>In that case you would not need the extra stream.&nbsp; I guess the code would look something like this:</p>\r\n<div style=\"color: black; background-color: white;\">\r\n<pre>          XmlDocument xmldoc_core = <span style=\"color: blue;\">new</span> XmlDocument();\r\n          <span style=\"color: blue;\">using</span> (MemoryStream ms1 = <span style=\"color: blue;\">new</span> MemoryStream()) \r\n          {\r\n              <span style=\"color: green;\">// We actually check if extracting worked in the working sample</span>\r\n              zip[<span style=\"color: #a31515;\">\"\\\\somepath\\\\somefile.xml\"</span>].Extract(ms); \r\n              ms1.Seek(0, SeekOrigin.Begin);\r\n\r\n              xmldoc_core.Load(ms1);\r\n          }\r\n          <span style=\"color: green;\">// This class function takes the xmldocument and modifies it by</span>\r\n          <span style=\"color: green;\">// appending some nodes, nothing fancy.</span>\r\n        \r\n          xmldoc_core = update_document(xmldoc_core, <span style=\"color: #a31515;\">\"1\"</span>, <span style=\"color: #a31515;\">\"2\"</span>, <span style=\"color: #a31515;\">\"3\"</span>, textBoxRevision.Text);\r\n          <span style=\"color: green;\">// xmldoc is valid, commence pushback</span>\r\n\r\n          <span style=\"color: green;\">// ** Note 1: Why assign the output of the above?  If the method</span>\r\n          <span style=\"color: green;\">// simply modifies the XmlDocument, why do you need to assign</span>\r\n          <span style=\"color: green;\">// the value?  Check your implementation.</span>\r\n        \r\n          <span style=\"color: green;\">// Remove and re-add</span>\r\n          zip.RemoveEntry(<span style=\"color: #a31515;\">\"\\\\somepath\\\\somefile.xml\"</span>);\r\n          zip.AddEntry(<span style=\"color: #a31515;\">\"\\\\somepath\\\\somefile.xml\"</span>, (name,stream) =&gt; {\r\n                  xmldoc_core.Save(stream);\r\n              });\r\n\r\n          <span style=\"color: green;\">// This will fail with IOException = sharing violation, file in use</span>\r\n          zip.Save();\r\n\r\n</pre>\r\n</div>",
    "PostedDate": "2011-03-09T07:49:04.46-08:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  }
]