views:

225

answers:

3

I am trying to save an XDcoument to a thumb drive which doesnt have enough memory space available. (This is a special test condition for the app) Though the application is giving an exception like below, I cant get that in the try catch block around the XDocument.Save(filePath). Looks like it is a delayed throw. Is it a LINQ issue or am I doing something wrong?.

alt text

 System.IO.IOException was unhandled
 Message="There is not enough space on the disk.\r\n"
 Source="mscorlib"
 StackTrace:
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.WriteCore(Byte[] buffer, Int32 offset, Int32 count)
   at System.IO.FileStream.FlushWrite(Boolean calledFromFinalizer)
   at System.IO.FileStream.Dispose(Boolean disposing)
   at System.IO.FileStream.Finalize()
+1  A: 

Look at the stack trace. This trace starts with a Finalize call, which does a Dispose, which does a FlushWrite, which calls WriteCore, which gets the error.

In other words, flush your data first.

Post the code you use to write and we can show you where to do the flush.

John Saunders
A: 

Peeking into reflector, the last few lines are

 using (XmlWriter writer = XmlWriter.Create(fileName, xmlWriterSettings))
 {
     this.Save(writer);
 }

It means, the exception is thrown when the writer is disposed.
I guess, it will be better to check for available disk space before calling Save.

EDIT: Have you Disposed any object that the instance of XDocument depended on before making a call to Save?

shahkalpesh
The last few lines of what? Also, that's not consistent with the stack trace. There would be no Finalize method on the stack.
John Saunders
Checking for disk space won't save you if another process uses up the disk space you were going to use for your process after you perform the check.
Erik Forbes
@Erik: There could be several such scenarios, if one has to make things foolproof :) The OP can see if the scenario you described, is a valid case or not.
shahkalpesh
+2  A: 

You found a bug in framework. XDocument.Save(string) uses the "using" statement to ensure the output stream gets disposed. It depends on the encoding you used in the processing instruction but the internal System.Xml.XmlUtf8RawTextReader would be a common one to implement the text writer.

The bug: the Microsoft programmer that wrote that class forgot to implement the Dispose() method. Only the Close() method is implemented.

It is rather strange that this bug wasn't yet reported at the connect.microsoft.com feedback site. It ought to cause trouble in general use because the file stays open until the finalizer thread runs. Although that normally doesn't take that long, a couple of seconds or so. Except in your case where you exit the program right after writing and have the unfortunate luck to run out of disk space at the exact moment the buffer gets flushed.

A workaround for this bug is to use the XDocument.Save(TextWriter) overload instead, passing a StreamWriter whose Encoding matches the encoding of the XML.

Hans Passant
Hey thanks for the answer. In my case I am purposefully made my thumb drive less space than what I need, This is a test condition I am checking.
Jobi Joy
Well, another side-effect of the bug is that you wouldn't be able to eject your thumb drive.
Hans Passant