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(); }
}
Related
I have some doubts regarding the using statement:
I have a class called
MyJob which is Disposable. Then i also have a property on MyJob JobResults that is also Disposable.
MY code:
using (MyJob job = new MyJob())
{
//do something.
FormatResults(job.JobResults)
}
public string FormatResuls(JobResuts results)
{
}
MY First question is: In this case after the using block are both MyJob and MyJob.Results disposed or only MyJob and NOT MyJob.Results?
I am also performing parallel processing w.r.t Tasks in C#:
Tasks allTasks = List<Tasks>
try
{
foreach(Task t in allTasks)
{
// Each tasks makes use of an IDisposable object.
t.Start();
}
Task.WaitAll(allTasks);
}
catch(AggregateExecption aex)
{
/// How do I ensure that all IDisposables are disposed properly if an exception happens in any of the tasks?
}
My second q, in the code above, what is the proper way to ensure to dispose off objects correctly when handling exceptions in tasks?
Sorry if my questions are too naive or confusing, as i am still trying to learn and understand C#.
Thanks guys!
are both MyJob and MyJob.Results disposed or only MyJob and NOT
MyJob.Results?
That is subjective to the implementation of your Dispose method. As we haven't seen it in your question, I'll assume that you aren't currently disposing your Result property in MyJob.Dispose, hence it will be the latter.
As only MyJob is wrapped in a using statement, and again assuming it does nothing to your Result property, it will be disposed as opposed to Results, which isn't wrapped in a using statement.
You could decide that MyJob, as it encapsulates your Result property, is responsible for the disposable of it as well. If you decide so, you can dispose Results in MyJobs.Dispose.
what is the proper way to ensure to dispose off objects correctly when
handling exceptions in tasks?
If the delegate which is passed to the Task is wrapped in a using statement, you are safe, since using will transform your code to a try-finally block, if an exception occurs in your using block, the finally block will still run yourObject.Dispose.
Only MyJobs is disposed. For other properties, you need to understand object ownership: who owns the object should be responsible (in general) to dispose of it. A property implementing IDisposable could be used by other instances, so you can only dispose of it if you are the one who created it and there no other references to it, or the class fails gracefully if it knows that it has been disposed of.
There are a lot of good answers here but one thing remains. If you want to be assured that your object is properly disposed because it uses unmanaged resources, you should implement a destructor in your object, like:
class MyJob : IDisposable
{
private bool _disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
//Dispose unmanaged resources and any child disposables here
}
}
void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
~MyJob()
{
//ONLY use if you have unmanaged resources that DO NOT
//implement their own finalizers.
Dispose();
}
}
However, it is recommended that you DO NOT use a finalizer (destructor) unless you are finalizing a type with unmanaged resources that does not include its own finalizer.
See https://msdn.microsoft.com/en-us/library/b1yfkh5e.aspx for best practices on implementing IDisposable.
1) The best way is to dispose JobResults inside of MyJob's Dispose() methode. Otherwise it's not disposed on it's own
2) I would implement the finally part, go through every object and dispose it. But in most cases you donät need to do that read this
Say I have the following:
public abstract class ControlLimitBase : IDisposable
{
}
public abstract class UpperAlarmLimit : ControlLimitBase
{
}
public class CdsUpperAlarmLimit : UpperAlarmLimit
{
}
Two Questions:
1.
I'm a little confused on when my IDisposable members would actually get called. Would they get called when an instance of CdsUpperAlarmLimit goes out of scope?
2.
How would I handle disposing of objects created in the CdsUpperAlarmLimit class? Should this also derive from IDisposable?
Dispose() is never called automatically - it depends on how the code is actually used.
1.) Dispose() is called when you specifically call Dispose():
myAlarm.Dispose();
2.) Dispose() is called at the end of a using block using an instance of your type.
using(var myAlarm = new CdsUpperAlarmLimit())
{
}
The using block is syntactic sugar for a try/finally block with a call to Dispose() on the object "being used" in the finally block.
No, IDisposable won't be called just automatically. You'd normally call Dispose with a using statement, like this:
using (ControlLimitBase limit = new UpperAlarmLimit())
{
// Code using the limit
}
This is effectively a try/finally block, so Dispose will be called however you leave the block.
CdsUpperAlarmLimit already implements IDisposable indirectly. If you follow the normal pattern for implementing IDisposable in non-sealed classes, you'll override void Dispose(bool disposing) and dispose your composed resources there.
Note that the garbage collector does not call Dispose itself - although it can call a finalizer. You should rarely use a finalizer unless you have a direct handle on unmanaged resources though.
To be honest, I usually find it's worth trying to change the design to avoid needing to keep hold of unmanaged resources in classes - implementing IDisposable properly in the general case is frankly a pain. It's not so bad if your class is sealed (no need for the extra method; just implement the Dispose() method) - but it still means your clients need to be aware of it, so that they can use an appropriate using statement.
IDisposable has one member, Dispose().
This is called when you choose to call it. Most typically that's done for you by the framework with the using block syntactic sugar.
I'm a little confused on when my IDisposable members would actually get called. Would they get called when an instance of CdsUpperAlarmLimit goes out of scope?
No. Its get called when you use using construct as:
using(var inst = new CdsUpperAlarmLimit())
{
//...
}//<-------- here inst.Dispose() gets called.
But it doesn't get called if you write this:
{
var inst = new CdsUpperAlarmLimit();
//...
}//<-------- here inst.Dispose() does NOT get called.
However, you can write this as well:
var inst = new CdsUpperAlarmLimit();
using( inst )
{
//...
}//<-------- here inst.Dispose() gets called.
The best practice recommend when you implement Dispose() method in non sealed class you should have a virtual method for your derived classes to override.
Read more on Dispose pattern here http://www.codeproject.com/KB/cs/idisposable.aspx
when using an IDisposable object, it's always good to use it this way:
using(var disposable = new DisposableObject())
{
// do you stuff with disposable
}
After the using block has been run, the Dispose method will be called on the IDisposable object. Otherwise you would need to call Dispose manually.
When someone calls .Dispose on it.
No, it already implements it through inheritance.
IDisposable is implemented when you want to indicate that your resource has dependencies that must be explicitly unloaded and cleaned up. As such, IDisposable is never called automatically (like with Garbage Collection).
Generally, to handle IDisposables, you should wrap their usage in a using block
using(var x = new CdsUpperAlarmLimit()) { ... }
this compiles to:
CdsUpperAlarmLimit x = null;
try
{
x = new CdsUpperAlarmLimit();
...
}
finally
{
x.Dispose();
}
So, back to topic, if your type, CdsUpperAlarmLimit, is implementing IDisposable, it's saying to the world: "I have stuff that must be disposed". Common reasons for this would be:
CdsUpperAlarmLimit keeps some OTHER IDisposable resources (like FileStreams, ObjectContexts, Timers, etc.) and when CdsUpperAlarmLimit is done being used, it needs to make sure the FileStreams, ObjectContexts, Timers, etc. also get Dispose called.
CdsUpperAlarmLimit is using unmanaged resources or memory and must clean up when it's done or there will be a memory leak
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.
I have a method, which has a try/catch/finaly block inside. Within the try block, I declare SqlDataReader as follows:
SqlDataReader aReader = null;
aReader = aCommand.ExecuteReader();
In the finally block, the objects which are manually disposed of are those which are set at the class level. So objects in the method which implement IDisposable, such as SqlDataReader above, do they get automatically disposed of? Close() is called on aReader after a while loop executes to get the contents of the reader (which should be Dispose() as that calls Close()). If there is no call to Close(), would this object be closed/disposed of automatically when the method finishes or the object goes out of scope?
EDIT: I am aware of the using statement but there are scenarios which are confusing me.
No, objects are not automatically disposed when they go out of scope.
They're not even guaranteed to be disposed if/when they're garbage-collected, although many IDisposable objects implement a "fallback" finaliser to help ensure that they're eventually disposed.
You are resposible for ensuring that any IDisposable objects are disposed, preferably by wrapping them in a using block.
You should use a using {...} block to wrap your IDisposable objects in - the Dispose() method (which for SqlDataReader passes off to the Close() method) will be called when the using block ends. If you do not use using, the object will not be automatically disposed when it goes out of scope - it will be up to the object finalizer, if it has one, to get rid of resources when it is garbage collected
using (SqlDataReader aReader = aCommand.ExecuteReader())
{
// ... do stuff
} // aReader.Dispose() called here
I agree with all of the above. You should make sure you call Dispose() yourself, and the easiest way to to this is with the using statement (you can also do this yourself in the finally block - this is more verbose, but sometimes necessary). If you don't do this you can find your application leaking unmanaged resources such as handles, or even unmanaged memory, especially if somewhere underneath all of this some COM components are being used, or calls are being made into the Win32 API. This can obviously lead to performance and stability problems, as well as excessive resource usage.
Just because objects that implement IDisposable "should" implement a finaliser that calls their Dispose(bool disposing) method to free unmanaged resources, is no guarantee that this will happen, so you definitely should not rely on it. See, for example, http://msdn.microsoft.com/en-us/library/b1yfkh5e%28VS.71%29.aspx for more information on this point.
Also, something else to bear in mind, is that if your type has members that are disposable, your type should either implement IDisposable (unless the lifecycle of those members is managed by another type, which obviously might get messy), or, if you only use such members in one method, or to implement one particular piece of functionality, you should consider making them local variables/parameters in the methods that use them.
The Dispose pattern doesn't make any guarantees about which objects will call Dispose on which other objects; it may happen sometimes, but you shouldn't care. Instead, it's your responsibility to make sure Dispose() is called for all IDisposable objects. The best way to do that is with the using statement. For example:
using (SqlDataReader aReader = aCommand.ExecuteReader())
{
// your code
}
I am puzzled by the statement "In the finally block, the objects which are manually disposed of are those which are set at the class level." By objects set at the class level, do you mean fields? You probably shouldn't be disposing of these within a ordinary method, because then the life-time of the fields is unpredictable, and depends on which methods you happened to have called. It would be better to implement IDisposable and dispose of fields in your Dispose method.
Might the Using statement help?
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.