using (FileStream fileStream = new FileStream(path))
{
// do something
}
Now I know the using pattern is an implementation of IDisposable, namely that a Try/Catch/Finally is set up and Dispose is called on the object. My question is how the Close method is handled.
MSDN says that it is not called, but I have read otherwise.
I know that the FileStream inherrits from Stream which is explained here. Now that says not to override Close() because it is called by Dispose().
So do some classes just call Close() in their Dispose() methods or does the using call Close()?
The using statement only knows about Dispose(), but Stream.Dispose calls Close(), as documented in MSDN:
Note that because of backward
compatibility requirements, this
method's implementation differs from
the recommended guidance for the
Dispose pattern. This method calls
Close, which then calls
Stream.Dispose(Boolean).
using calls Dispose() only. The Dispose() method might call Close() if that is how it is implemented.
Close() is not part of the IDisposable interface so using has no way to know whether it should be called or not. using will only call Dispose(), but intelligently designed objects will close themselves in the Dispose() method.
I don't think the using calls Close(), it would have no way of knowing that it should call that particular function. So it must be calling dispose, and that in turn is calling close.
In .Net classes Close() call Dispose(). You should do the same.
Related
Is Close() same as Dispose() or using statement. Is it necessary to call using statement even if Close is called?.
I know before disposing of an object, close should be called, so we close the resource and may it available to Dispose.
https://msdn.microsoft.com/en-us/library/aa355056(v=vs.110).aspx
says Close is same as Dispose.
Is Close() same as Using statement?
No it is not.
Should you call Close() after a using?
No, it will break due to access to the disposed object.
Should I call Close() before exiting the using block?
It's complicated. If the IDisposable interface is implemented correctly: no. Otherwise: possibly.
Close() has no relation to IDisposable interface, see: https://msdn.microsoft.com/en-us/library/system.idisposable(v=vs.110).aspx
using only applies to IDisposable inherited objects, see: https://msdn.microsoft.com/en-us/library/yh598w02.aspx
Thus:
Close() and Dispose() may not considered to be related in any way.
When the IDisposable interface is correctly implemented, you may assume all clean-up necessary will be carried out. This implies an internal call to a Close() method would be carried out. This means that an explicit call to Close() should not be necessary.
The other way round; when a object is of type IDisposable and exposes a Close() method, a call to Close() will not be sufficient to properly dispose/clean-up the object. Dispose() must still be called, you can do this directly, or through the using statement.
You can also let the garbage-collector handle the Dispose() call for you (if its correctly implemented, see: Proper use of the IDisposable interface) But this is considered bad-practice, since you need to rely on a proper implementation and have no direct control over the GC timing.
Please note, a reason to implement a Close() function, is usually to give a developer a way to reuse the object. After calling Dispose() the object is considered to be marked for finalization and may not be used any more.
The using pattern is useful because it includes a try ... finally ... that will protect against exceptions...
If you do:
FileStream fs = null;
try
{
fs = File.OpenRead("MyFile.txt");
}
finally
{
if (fs != null)
{
fs.Close();
}
}
then in this case it would be nearly equivalent (because the Stream.Close() calls the Dispose(true))
BUT it is still "wrong"... You use using for IDisposable classes unless you have a very very good reason (there are some reasons for not doing it... Sometimes the lifetime of an object is very very difficult to track. In that case it is normally ok to no Dispose() it.).
The concept of a pattern is that it should become part of you... If you try to skirt from a pattern, then before or later you'll forget about it... And for what? For writing MORE lines that are MORE error-prone?
Not necessarily. I can write a class that has a Close and a Dispose method that aren't related.
class Foo : IDisposable
{
public void Close() { DoBar(); }
public void Dispose() { DoBaz(); }
}
This question already has answers here:
What is the C# Using block and why should I use it? [duplicate]
(9 answers)
Closed 9 years ago.
I was wondering if it necessary to call Close() in the following situation (if not necessary, why?)
using (var file = System.IO.File.OpenText(myFilePath))
{
...
}
I presume it is necessary in the following situation
StreamWriter file2 = new System.IO.StreamWriter(myFilePath);
newFileContents.ForEach(file2.WriteLine);
file2.Close();
Is it correct?
Edit:
I thought my question is close() - specific, might have been the difference between reading and writing....
With the using construct you get IDisposable.Dispose called automatically at the end of the code block which will close the file. If you don't use the using statement you have to call Close yourself.
With using you also automatically get built-in try/finally exception handling which will behave more gracefully if something goes wrong before you exit your using block. That's another reason using using is a good idea instead of rolling your own.
In your case the using construct is shorthand for:
StreamWriter file2 = new System.IO.StreamWriter(myFilePath);
try
{
newFileContents.ForEach(file2.WriteLine);
}
finally
{
if (file2!= null)
((IDisposable)file2).Dispose();
}
If you decompile StreamWriter's implementation of Dispose you will see this call (among others):
this.stream.Close();
in the finally block (If you need absolute proof ;-)
OpenText returns a StreamReader, which inherits TextReader, which inherits the IDisposable interface, which specifies a Dispose() method.
When the using statement goes out of scope, it calls the Dispose() method on the StreamReader's implementation of Dispose(), which in turn closes the stream (i.e. the underlying file) The whole thing is wrapped in a try/finally block under the covers, which guarantees that Dispose() will always be called.
the using structure calls the object's Dispose method when it reaches the end of the script block. This method closes the file.
Any time you work with a file, you need to make sure to call Dispose or Close in order to let Windows know that the file is free for editing.
Correct.
If wrapped in using clause, a file.Close() is not required
If not wrapped, you are responsible for Close() and Dispose()
I was wondering if it necessary to call Close() in the following situation (if not necessary, why?)
No because the using statement disposes of the object - and thus removes unmanaged resources.
I presume it is necessary in the following situation
Yes, here it would be required so that the unmanaged resources were cleaned up.
It's not necessary because Dispose() will close the underlying file. However since that's an implementation detail it's good practice to explicitly call Close() when you're done with the stream.
Hi
When i use following code:
myManualResetEvent.Dispose();
Compiler gives this error:
'System.Threading.WaitHandle.Dispose(bool)' is inaccessible due to its protection level.
howevr following line works fine:
((IDisposable)myManualResetEvent).Dispose();
is it the correct way to dispose or at runtime it might crash in some scenerios.
Thanks.
The designers of the .NET Base Class Library decided to implement the Dispose method using explicit interface implementation:
private void IDisposable.Dispose() { ... }
The Dispose method is private and the only way to call it is to cast the object to IDisposable as you have discovered.
The reason this is done is to customize the name of the Dispose method into something that better describes how the object is disposed. For a ManualResetEvent the customized method is the Close method.
To dispose a ManualResetEvent you have two good options. Using IDisposable:
using (var myManualResetEvent = new ManualResetEvent(false)) {
...
// IDisposable.Dispose() will be called when exiting the block.
}
or calling Close:
var myManualResetEvent = new ManualResetEvent(false);
...
// This will dispose the object.
myManualResetEvent.Close();
You can read more in the section Customizing a Dispose Method Name in the design guideline Implementing Finalize and Dispose to Clean Up Unmanaged Resources on MSDN:
Occasionally a domain-specific name is more appropriate than Dispose. For example, a file encapsulation might want to use the method name Close. In this case, implement Dispose privately and create a public Close method that calls Dispose.
WaitHandle.Close
This method is the public version of
the IDisposable.Dispose method
implemented to support the IDisposable
interface.
According to the documentation, WaitHandle.Dispose() and WaitHandle.Close() are equivalent. Dispose exists to allow closing though the IDisposable interface. For manually closing a WaitHandle (such as a ManualResetEvent), you can simply use Close directly instead of Dispose:
WaitHandle.Close
[...]
This method is the public version of the IDisposable.Dispose method implemented to support the IDisposable interface.
From the resource clean-up perspective, why there are Response.Close() and Response.Dispose() and which one is more comprehensive (call the other one) ?
Where both methods are provided the implementation of Dispose should call Close. It is a good idea to use the using statement to ensure that Disposeand therefore Close is called, even if there is an exception.
In other words do this:
using (Response response = ...)
{
// ...
}
Not this:
Response response = ...;
// ...
response.Close(); // If there is an exception this might never get called!
One difference between closing and disposing an object is that when you dispose an object it usually is not possible to use the object any more (attempting to do so may cause an ObjectDisposedException to be thrown), but after calling Close it may be possible to still use the object.
Note that if you are talking about ASP.NET then you shouldn't normally call Close or Dispose on the Response object.
From the Design Guidelines for Developing Class Library on Implementing Finalize and Dispose to Clean Up Unmanaged Resources
Occasionally a domain-specific name is
more appropriate than Dispose. For
example, a file encapsulation might
want to use the method name Close. In
this case, implement Dispose privately
and create a public Close method that
calls Dispose. The following code
example illustrates this pattern. You
can replace Close with a method name
appropriate to your domain. This
example requires the System namespace.
/ Do not make this method virtual.
// A derived class should not be allowed
// to override this method.
public void Close()
{
// Call the Dispose method with no parameters.
Dispose();
}
Typically I've seen close whenever the resource can be opened or re-opened, since it gives nice symmetry to the method names.
Response.Close() closes the socket connection to a client.
Response.Dispose() is method which implements IDisposable interface and releases allocated resources.
I think Response.Close() is called from Response.Dispose() method.
For more detailed information you can use Reflector
Which one do I call?
Is it necessary to call both?
Will the other throw an exception if I have already called one of them?
Close() and Dispose(), when called on a MemoryStream, only serve to do two things:
Mark the object disposed so that future accidental usage of the object will throw an exception.
Possibly1 release references to managed objects, which can make the GC's job a bit easier depending on the GC implementation. (On today's GC algorithms it makes no real difference, so this is a point for an academic discussion and has no significant real-world impact.)
MemoryStream does not have any unmanaged resources to dispose, so you don't technically have to dispose of it. The effect of not disposing a MemoryStream is roughly the same thing as dropping a reference to a byte[] -- the GC will clean both up the same way.
Which one do I call? Is it necessary to call both?
The Dispose() method of streams delegate directly to the Close() method2, so both do exactly the same thing.
Will the other throw an exception if I have already called one of them?
The documentation for IDisposable.Dispose() specifically states it is safe to call Dispose() multiple times, on any object3. (If that is not true for a particular class then that class implements the IDisposable interface in a way that violates its contract, and this would be a bug.)
All that to say: it really doesn't make a huge difference whether you dispose a MemoryStream or not. The only real reason it has Close/Dispose methods is because it inherits from Stream, which requires those methods as part of its contract to support streams that do have unmanaged resources (such as file or socket descriptors).
1 Mono's implementation does not release the byte[] reference. I don't know if the Microsoft implementation does.
2 "This method calls Close, which then calls Stream.Dispose(Boolean)."
3 "If an object's Dispose method is called more than once, the object must ignore all calls after the first one."
None of the above. You needn't call either Close or Dispose.
MemoryStream doesn't hold any unmanaged resources, so the only resource to be reclaimed is memory. The memory will be reclaimed during garbage collection with the rest of the MemoryStream object when your code no longer references the MemoryStream.
If you have a long-lived reference to the MemoryStream, you can set that reference to null to allow the MemoryStream to be garbage collected. Close and Dispose free neither the steam buffer nor the MemoryStream object proper.
Since neither Stream nor MemoryStream have a finalizer, there is no need to call Close or Dispose to cause GC.SuppressFinalize to be called to optimize garbage collection. There is no finalizer to suppress.
The docs for MemoryStream put it this way:
This type implements the IDisposable interface, but does not actually have any resources to dispose. This means that disposing it by directly calling Dispose() or by using a language construct such as using (in C#) or Using (in Visual Basic) is not necessary.
You can use the using block for this. It will automatically call Dispose when it goes outside of its scope.
Example:
using (MemoryStream ms = new MemoryStream())
{
// Do something with ms..
}
// ms is disposed here
Hope this helped.
Use using block so that your object is disposed if its implements IDisposable interface
the following code is Stream.Dispose from reflector as you can see, you don't need to close if you dispose (which is implicit when using using)
public void Dispose()
{
this.Close();
}
Which one do I call?
Any of them.
Is it necessary to call both?
No, either one is sufficient.
Will the other throw an exception if I have already called one of them?
No, disposable pattern declares that subsequent calls to Dispose don't cause negative effects.
Calling Close() will internally call Dispose() to release the resources.
See this link for more information:
msdn
Calling only Dispose() will do the trick =)
In .NET 3.5 (haven't checked other versions), methods are called in the following order when disposing a MemoryStream:
Stream.Dispose()
simply calls Close
Stream.Close()
calls Dispose(true), then GC.SuppressFinalize(this)
MemoryStream.Dispose(true)
sets _isOpen , _writable, and _expandable flags to false
Stream.Dispose(true)
closes async event if active
As a first solution, it's recommended to use using statements wherever possible. This is described here: http://msdn.microsoft.com/en-us/library/yh598w02.aspx
When the lifetime of an IDisposable object is limited to a single method, you should declare and instantiate it in the using statement. The using statement calls the Dispose method on the object in the correct way, and (when you use it as shown earlier) it also causes the object itself to go out of scope as soon as Dispose is called. Within the using block, the object is read-only and cannot be modified or reassigned.
Coming to the question now, as others suggested in most .NET framework classes, there is no difference between Close() and Dispose() and it doesn't matter which of the two methods you call. You should call one but not both. However, there are exceptions.
There are exceptions; for example, System.Windows.Forms.Form and System.Data.SqlClient.SqlConnection have different behavior for Close() and Dispose().
For complete details, you can check here: https://blogs.msdn.microsoft.com/kimhamil/2008/03/15/the-often-non-difference-between-close-and-dispose/