Is it true that this does not necessarily mean the stream has been disposed of by code - either in a using or by calling dispose.
The stream could have been closed outside of this code and this exception would still occur?
So I will make my comment an answer: Yes, a stream could just as well be closed from outside your code, so make sure you check for a System.ObjectDisposedException.
There are several occasions this could happen: imagine for example a stream associated with a network connection and the connection is suddenly interrupted. Depending on the implementation this could close the stream and throw that particular exception if the stream is accessed.
The stream could have been closed outside of this code and this exception would still occur?
Yes. For example - This can happen if you wrap a stream within another stream, and dispose of the "wrapper" stream. Many implementations dispose of the stream they are wrapping.
If you then try to write to the "wrapped" stream, you'll receive this error message.
either in a using or by calling dispose.
Also realize that, for objects which have a Close() method, such as Stream, Close and Dispose typically perform the same function. Closing a stream also disposes of it.
This error can also happen if the requestLengthDiskThreshold is smaller than the size of the file you are trying to upload/handle via the stream. This is defined in your web.config:
<httpRuntime maxRequestLength="512000" requestLengthDiskThreshold="512000" />
If you loook at the explanation for the 2nd parameter here:
https://msdn.microsoft.com/en-us/library/system.web.configuration.httpruntimesection.requestlengthdiskthreshold(v=vs.110).aspx
you will see that it sets the input-stream buffering threshold (in kilobytes). The default value is 80KB so if you don't have this value set and you try, for example, to ajax upload the file bigger than 80KB you will get the System.ObjectDisposedException exception since the stream will be closed once the threshold limit is met.
In my case I'm setting the threshold to 500MB...
Related
This question already has answers here:
IOException: The process cannot access the file 'file path' because it is being used by another process
(12 answers)
Closed 1 year ago.
When I change selection in a list, the dialog gets updated, reading from the file associated with that item in the list. I fixed the problem by using the using statement in below code.
private void ViewModel_SelectedNoteChanged(object sender, EventArgs e)
{
try
{
contentRichTextBox.Document.Blocks.Clear();
if (VM.SelectedNote != null)
{
if (!string.IsNullOrEmpty(VM.SelectedNote.FileLocation))
{
using (FileStream fileStream = new FileStream(VM.SelectedNote.FileLocation, FileMode.Open))
{
var contents = new TextRange(contentRichTextBox.Document.ContentStart, contentRichTextBox.Document.ContentEnd);
contents.Load(fileStream, DataFormats.Rtf);
}
}
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
If I don't use the using statement above, its hit or miss. Sometimes it reads the contents from a file and display them, otherwise it throws an exception.
System.IO.IOException: 'The process cannot access the file
'D:\EClone\bin\Debug\netcoreapp3.1\3.rtf'
because it is being used by another process.'
My question is why the unpredictable behavior without the using statement? Is it because of known unpredictability of garbage collection (when it decides to clean up), because we can never be sure when does the garbage collection cleans up the file? Is this a good example of non-deterministic nature of garbage collection? Or is it something else?
This is exactly due to incorrect usage of IDisposable and GC.
Without using
you open file (and thus lock it) and store a reference in a variable
the function exits, but the file is still opened and locked.
if GC runned before you will try to open file again - all works fine, because in a file wrapper's finalizer there is a code to close (and unlock) a file.
if you try to access the same file before GC run - you will get exception.
In case with using, you will close and unlock file explicitly by calling Dispose (using will call it for you). Dispose will close and unlock file immediately without waiting GC, so with using your code will always work as expected.
Moreover, as you can't control, when the GC will run, the code without using is unstable by design, so even if it works fine today, it may stop working tomorrow because of the system have more free memory (and GC runs no so often as today), or because .net update (with some GC changes/improvements) and so on.
So, as conclusion: if you have something, which implements IDisposable, always call Dispose when you not need the object anymore (with using or manually). You can omit calling Dispose only if it is explicitly allowed in documentation or guides (for example, as for Task class)
I cannot understand why I need to dispose the File.Create or wrap the creation within a using station before accessing the file and write to it. Why do I need to dispose that instances of Stream class that File.Create initialized, and have to create another Stream instance to write to it? Are they on a different thread, why?
Why can't creation, text-writing, and deletion share the same Stream? Perhaps I just do not understand Stream.
For example:
File.Create(...);
File.ReadLine(...); <-- The process cannot access the file ... because it is being used by another process
using (File.Create(...)) {};
File.ReadLine(...); <-- OK
See the Remarks section on the File.Create page on MSDN (emphasis mine):
The FileStream object created by this method has a default FileShare
value of None; no other process or code can access the created file
until the original file handle is closed.
I had thought that it was good practice, when accessing embedded assembly resources using the Assembly.GetManifestResourceStream method, to close the returned Stream after finishing with it. However, I just spotted something in the following article:
http://msdn.microsoft.com/en-us/library/ms950960.aspx
// Get the stream that holds the resource
// NOTE1: Make sure not to close this stream!
// NOTE2: Also be very careful to match the case
// on the resource name itself
Stream stream =
assem.GetManifestResourceStream("Azul.jpg");
// Load the bitmap from the stream
this.BackgroundImage = new Bitmap(stream);
The comment here says that the stream should not be closed, though the article makes no mention of why. Searches on Google have provided nothing conclusive; some people seem to close this stream, others don't and say the garbage collector will deal with it.
Should I close streams returned by Assembly.GetManifestResourceStream? Is there a particular reason I shouldn't?
That comment doesn't want you to close it because it goes on to create a Bitmap object from it.
Generally, you should close the streams once you're done using them or your application will be subject to memory leaks.
I have a class that essentially wraps a Stream for reading/writing, but that stream is expected to be managed by the consumer of that class. For ease of use, I use StreamReader and StreamWriter classes to perform I/O operations on the stream. Normally I'd wrap the reader and writer in using blocks, but I want to avoid closing the reader and writer because doing so also closes the underlying stream and I have to keep it open.
Is it safe in terms of memory/resource management to not close a StreamReader/StreamWriter if I expect the underlying Stream to be managed by the caller? Will the reader and writer be garbage collected when the stream is explicitly closed elsewhere?
public class Wrapper
{
private Stream _underlyingStream;
public Wrapper(Stream underlyingStream)
{
_underlyingStream = underlyingStream;
}
public string GetValue()
{
_underlyingStream.Seek(0, SeekOrigin.Begin);
var reader = new StreamReader(_underlyingStream);
return reader.ReadToEnd(); // we're done, but the stream is not ours to close
}
}
If nobody closes the streams then ultimately the finalizer will be called which should call dispose and close them upon GC. But that's quite a crap-shoot resource-wise because it leaves whatever possibly-expensive resources allocated until GC. It could get worse the longer your object lives, especially if it survives collections to be promoted to gen 1 or even 2.
It sure would be nice if you could present something to your caller that isolates this. Perhaps you can cache something from the stream so you can close it while still serving the content to your caller?
EDIT after your edit: Now that I see your caller PASSES you a stream to operate on, my answer has to be different! It's very clear that your caller should be managing the stream's lifetime. I had the impression at first that your class created a stream and hoped the caller managed it.
The easiest way to solve this is to wrap the stream in your own class that derives from System.IO.Stream
Example:
http://csharptest.net/browse/src/Library/IO/NonClosingStream.cs
It is definetelly not ok.
read this from msdn
The close calls the Dispose method passing a true value.
Flushing the stream will not flush its underlying encoder unless you explicitly call Close.
Try to encapsulate all IO in a class.
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 http://img211.imageshack.us/img211/8324/exce.png
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()
You found a bug in the 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.
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.
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?
XDocument.Save(string) does not have a bug, it does implement the Dispose method. The using statement is:- (as also described above)
using (XmlWriter writer = XmlWriter.Create(fileName, xmlWriterSettings))
this.Save(writer);
And XmlWriter does have a Dispose(), it implement the IDisposable interface.