Will unassigned object to variable dispose automatically - c#

so lets say we have some thing like this websericeclient object
var myname = new WebServiceClient().GetName ( ) ;
what will happen to this object (WebServiceClient()) is it going to dispose automatically or stay in memory .

"Disposing" (calling IDisposable.Dispose()) has nothing to do with memory. It has to do with freeing unmanaged resources like file or database handles.
What happens when you don't call Dispose() is that these resources will remain until the finalizer is called when the Garbage Collector runs to free the object from memory. If you needed those resources (or if something interesting is meant to happen when they are Disposed()) then you don't want to wait some arbitrary period of time - call Dispose() as soon as you're done with it.

It depends on the _GetName()_ method. And on the _WebServiceClient()_.
Let's take the example:
public class WebServiceClient : IDisposable
{
private static WebServiceClient viciousReference = null;
public WebServiceClient()
{
viciousReference = this;
}
~WebServiceClient()
{
Dispose();
}
public void Dispose()
{
// Standard Dispose implementation
}
}
If your object implements Dispose(), always try to call it yourself. Don't only rely on the garbage collector.

Related

Writing a practical example of IDisposable

I've been reading about the Dispose pattern, and I kinda understand what's it for (cleaning up resources so my application won't leak memory) but I'd like to see it in a practical example.
My idea is to write a simple application that, first, uses some resources and does not dispose of them, and after some code changes, properly disposes those resources. What I'd like to see is the memory usage before/after the code changes to visualize how disposing helps.
Question: What objects can I use? I tried to do it with some big images (JPEG images 15+ MB in size) but I can't build a practical example out of it. Of course I'm open to other ideas.
This unit test does what you're describing. It does the same thing both with and without calling Dispose to show what happens without calling Dispose.
Both methods create a file, open the file, write to it, then open it again and write to it again.
The first method throws an IOException because the StreamWriter wasn't disposed. The file is already open and can't be opened again.
The second one disposes before trying to reopen the file, and that works without an exception.
[TestClass]
public class DisposableTests
{
[TestMethod]
[ExpectedException(typeof(IOException))]
public void DoesntDisposeStreamWriter()
{
var filename = CreateFile();
var fs = new StreamWriter(filename);
fs.WriteLine("World");
var fs2 = new StreamWriter(filename);
fs2.WriteLine("Doesn't work - the file is already opened.");
}
[TestMethod]
public void DisposesStreamWriter()
{
var filename = CreateFile();
var fs = new StreamWriter(filename);
fs.WriteLine("World");
fs.Dispose();
var fs2 = new StreamWriter(filename);
fs2.WriteLine("This works");
fs2.Dispose();
}
private string CreateFile()
{
var filename = Guid.NewGuid() + ".txt";
using (var fs = new StreamWriter(filename))
{
fs.WriteLine("Hello");
}
return filename;
}
}
You likely wouldn't see the problem with memory use because that's not specifically what IDisposable addresses. All objects use memory, but most aren't disposable. The garbage collector reclaims memory from objects that are no longer referenced (like an object that's created in a method but goes out of scope when the method ends.)
IDisposable is for scenarios where the class holds onto some resource that isn't garbage collected. Another example is SqlConnection. It's not about memory, it's about the connection to the SQL Server. There are only so many available. (It will eventually get released, but not in a predictable manner - that's a digression.)
The exact reasons why classes might be IDisposable vary. They often have nothing in common. IDisposable doesn't care what the reason is. It just means that there's something in the class that needs to be cleaned up.
The following example show the general best practice to implement IDisposable interface. Create some MyResouce instances and test it without calling Dispose method, there is a memory leak. Then call the Dispose everytime once you are finish with MyResouce instance, no memory leak. Reference
public class DisposeExample
{
// A base class that implements IDisposable.
// By implementing IDisposable, you are announcing that
// instances of this type allocate scarce resources.
public class MyResource: IDisposable
{
// Pointer to an external unmanaged resource.
private IntPtr handle;
// Other managed resource this class uses.
private Component component = new Component();
// Track whether Dispose has been called.
private bool disposed = false;
// The class constructor.
public MyResource(IntPtr handle)
{
this.handle = handle;
}
// Implement IDisposable.
// Do not make this method virtual.
// A derived class should not be able to override this method.
public void Dispose()
{
Dispose(true);
// This object will be cleaned up by the Dispose method.
// Therefore, you should call GC.SupressFinalize to
// take this object off the finalization queue
// and prevent finalization code for this object
// from executing a second time.
GC.SuppressFinalize(this);
}
// Dispose(bool disposing) executes in two distinct scenarios.
// If disposing equals true, the method has been called directly
// or indirectly by a user's code. Managed and unmanaged resources
// can be disposed.
// If disposing equals false, the method has been called by the
// runtime from inside the finalizer and you should not reference
// other objects. Only unmanaged resources can be disposed.
protected virtual void Dispose(bool disposing)
{
// Check to see if Dispose has already been called.
if(!this.disposed)
{
// If disposing equals true, dispose all managed
// and unmanaged resources.
if(disposing)
{
// Dispose managed resources.
component.Dispose();
}
// Call the appropriate methods to clean up
// unmanaged resources here.
// If disposing is false,
// only the following code is executed.
CloseHandle(handle);
handle = IntPtr.Zero;
// Note disposing has been done.
disposed = true;
}
}
// Use interop to call the method necessary
// to clean up the unmanaged resource.
[System.Runtime.InteropServices.DllImport("Kernel32")]
private extern static Boolean CloseHandle(IntPtr handle);
// Use C# destructor syntax for finalization code.
// This destructor will run only if the Dispose method
// does not get called.
// It gives your base class the opportunity to finalize.
// Do not provide destructors in types derived from this class.
~MyResource()
{
// Do not re-create Dispose clean-up code here.
// Calling Dispose(false) is optimal in terms of
// readability and maintainability.
Dispose(false);
}
}
public static void Main()
{
// Insert code here to create
// and use the MyResource object.
}
}

Where to call Dispose() of IDisposable created in constructor?

Where to call Dispose() for IDisposable objects owned by an object?
public class MyClass
{
public MyClass()
{
log = new EventLog { Source = "MyLogSource", Log = "MyLog" };
FileStream stream = File.Open("MyFile.txt", FileMode.OpenOrCreate);
}
private readonly EventLog log;
private readonly FileStream stream;
// Other members, using the fields above
}
Should I implement Finalize() for this example? What if I do not implement anything at all? Will there be any problems?
My first thought was that MyClass should implement IDisposable. But the following statement in an MSDN article confused me:
Implement IDisposable only if you are using unmanaged resources directly. If your app simply uses an object that implements
IDisposable, don't provide an IDisposable implementation.
Is this statement wrong?
If MyClass owns an IDisposable resource, then MyClass should itself be IDisposable, and it should dispose the encapsulated resource when Dispose() is called on MyClass:
public class MyClass : IDisposable {
// ...
public virtual void Dispose() {
if(stream != null) {
stream.Dispose();
stream = null;
}
if(log != null) {
log.Dispose();
log = null;
}
}
}
No, you should not implement a finalizer here.
Note: an alternative implemention might be something like:
private static void Dispose<T>(ref T obj) where T : class, IDisposable {
if(obj != null) {
try { obj.Dispose(); } catch {}
obj = null;
}
}
public virtual void Dispose() {
Dispose(ref stream);
Dispose(ref log);
}
For objects containing other IDisposable objects, it's a good and recommended practice to implement IDisposable on your own object, so others consuming your type can wrap it in a using statement:
public class MyClass : IDisposable
{
public MyClass()
{
log = new EventLog { Source = "MyLogSource", Log="MyLog" };
FileStream stream = File.Open("MyFile.txt", FileMode.OpenOrCreate);
}
private readonly EventLog log;
private readonly FileStream stream;
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// Free managed objects here
stream.Dispose();
}
}
// Other members, using the fields above
}
In your case, you aren't freeing up any managed resources so no finalizer is needed. If you were, then you would implement a finalizer and call Dispose(false), indicating to your dispose method that it is running from the finalizer thread.
If you don't implement IDisposable, you're leaving it up to the GC to clean up the resources (e.g, close the Handle on the FileStream you've opened) once it kicks in for collection. Lets say your MyClass object is eligible for collection and is currently in generation 1. You would be leaving your FileStream handle open until the GC cleans up the resource once it runs. Also, many implementations of Dispose call GC.SuppressFinalize to avoid having your object live another GC cycle, passing from the Initialization Queue to the F-Reachable queue.
Much of the advice surrounding Dispose and Finalize was written by people who expected Finalize to be workable as a primary resource cleanup mechanism. Experience has shown such expectation to have been overly optimistic. Public-facing objects which acquire any sort of resources and hold them between method calls should implement IDisposable and should not override Finalize. If an object holds any resources which would not otherwise get cleaned up if it was abandoned, it should encapsulate each such resource in a privately-held object which should then use Finalize to clean up that resource if required.
Note that a class should generally not use Finalize to clean up resources held by other objects. If Finalize runs on an object that holds a reference to the other object, one of several conditions will usually apply:
No other reference exists to the other object, and it has already run Finalize, so this object doesn't need to do anything to clean it up.
No other reference exists to the other object, and it hasn't yet run Finalize but is scheduled to do so, so this object doesn't need to do anything to clean it up.
Something else is still using the other object, so this object shouldn't try to clean it up.
The other object's clean-up method cannot be safely run from within the context of a finalizer thread, so this object shouldn't try to clean it up.
This object only became eligible to run Finalize because all necessary cleanup has already been accomplished, so this object doesn't need to do anything to clean things up.
Only define a Finalize method in those cases where one can understand why none of the above conditions apply. Although such cases exist, they are rare, and it's better not to have a Finalize method than to have an inappropriate one.

Should I dispose old object before assigning new object?

Lets assume we have two class Foo and Bar as given below.
public class Foo
{
public static Bar BarInstance { get; set; }
public static void Main()
{
AssignBar("A");
AssignBar("B");
}
private static void AssignBar(string name)
{
BarInstance = new Bar(name);
}
}
public class Bar : IDisposable
{
public Bar(string name)
{
Name = name;
}
public string Name { get; set; }
protected virtual void Dispose(bool disposing)
{
if (!disposing)
{
return;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
When object A gets replaced by object B. I expect Dispose to called because since there is no reference to Object A exists any more, but it doesn't get called. Could you please explain why?
Should I end up doing CurrentBar.Dispose like below if I want Object A to be disposed.
private static void AssignBar(string name)
{
if (BarInstance != null)
{
BarInstance.Dispose();
}
BarInstance = new Bar(name);
}
It depends on the ownership.
Is Bar given to Foo with the implication that Foo now owns Bar?
If so, then yes, you should call Dispose on the old before assigning a new instance.
Is Bar given to Foo with the implication that it's more of a loan, ie. you can reference and use this object, but it is owned by something else?
If so, then no, you should not call Dispose on the old before assigning a new instance.
Your code is not altogether clear on this point and I would suggest you clean that up, would make it easier to reason about this type in the future.
The way I see it you have 1 of 3 possible scenarios:
Foo always owns Bar. In this case I would put the disposal of the old instance in the setter of the property, or remove the public setter altogether if the only way to get a new Bar instance into it is through the method you have declared.
Foo never owns Bar. In this case I would not add any code that disposes of the old instance, but then I question the existence of that method. In this case it is likely nobody would really own the newly constructed instance.
Foo only owns Bar instances created through your method, but not instances given to it through the public setter. In this case I would add a new field that tracks whether Foo owns Bar or not, and set this to true in the method, and clear it in the property setter.
Dispose is not special in any way, from the C# standpoint it is just another method, as such there is nothing automatic that will call this method.
However, if the object references unmanaged resources, when the object at some point becomes eligible for collection, its finalizer will be executed releasing those unmanaged resources. However, to deterministically release them when you know they are no longer needed, you need to call Dispose.
Dispose is no special method. It will not be called automatically. You'll have to do it.
private static void AssignBar(string name)
{
if(BarInstance!=null)
{
BarInstance.Dispose();
}
BarInstance = new Bar(name);
}
I think you are confusing with finalizers and IDisposable. Finalizers are called at the time of garbage collection(not reliable though). If you have implemented DisposablePattern, then you'll have a Dispose(bool) method which is called from finalizer. Where finalizers are called by GC automatially during garbage collection.
Read here for more info
The runtime won't automatically call Dispose for you, it's your responsibility to ensure it's called. Your object will be garbage collected, but this only ensures that memory is reclaimed. It's up to use to release resources.
You can do this using either a using statement:
using(var x = new BarInstance())
{
// Whatever
}
or you can call it yourself. In your example, since you're replacing the instance you'll need to call Dispose, otherwise you risk a resource leak.
You could opt to use a finalizer in your class, ~Bar. In the finalizer you can dispose of any resources you're holding. However, when the finalizer will be called in non-deterministic, and it's even possible that it will never be called if the garbage collector doesn't kick in.

Should Dispose() or Finalize() be used to delete temporary files?

I have a class that makes use of temporary files (Path.GetTempFileName()) while it is active. I want to make sure these files do not remain on the user's hard drive taking up space after my program is closed. Right now my class has a Close() method which checks if any temporary files used by the class still exist and deletes them.
Would it make more sense to put this code in the Dispose() or Finalize() methods instead?
Better yet would be to create the file with FileOptions.DeleteOnClose. This will ensure that the operating system forcibly deletes the file when your process exits (even in the case of a rude abort). Of course, you will still want to close/delete the file yourself when you are done with it, but this provides a nice backstop to ensure that you don't allow the files to be sit around forever
Example:
using (FileStream fs = File.Create(Path.GetTempFileName(), Int16.MaxValue,
FileOptions.DeleteOnClose))
{
// Use temp file
} // The file will be deleted here
I would do both; make the class disposable, and have the finalizer clean it up. There is a standard pattern for doing so safely and effectively: use it rather than attempting to deduce for yourself what the right pattern is. It is very easy to get wrong. Read this carefully:
http://msdn.microsoft.com/en-us/library/system.idisposable.aspx
Note that you've got to be really really careful when writing a finalizer. When the finalizer runs, many of your normal assumptions are wrong:
There are all kinds of potentials for race conditions or deadlocks because you are no longer on the main thread, you're on the finalizer thread.
In regular code, if you're running code inside an object then you know that all the things the object refers to are alive. In a finalizer, all the things the object refers to might have just been finalized! Finalizers of dead objects can run in any order, including "child" objects being finalized before "parent" objects.
In regular code, assigning a reference to an object to a static field could be perfectly sensible. In a finalizer, the reference you are assigning could be to an already dead object, and therefore the assignment brings a dead object back to life. (Because objects referred to by static fields are always alive.) That is an exceedingly weird state to be in and nothing pleasant happens if you do.
And so on. Be careful. You are expected to fully understand the operation of the garbage collector if you write a non-trivial finalizer.
A file is an unmanaged resource, and you implement IDisposable to clean up unmanaged resources that your classes are dependent upon.
I have implemented similar classes, although never in production code.
However, I understand your tentativeness about this - user interaction with the files outside of your application could screw things up and cause problems during disposal. However, that is the same for any file created/deleted by an application, regardless of whether or not it's tidied up by a Dispose() method or not.
I'd have to say that implementing IDisposable would be a reasonable choice.
A nice way is suggested by David M. Kean on the MSDN entry on Path.GetTempFileName. He creates a wrapper class implementing IDisposable that will automatically remove the file:
public class TemporaryFile : IDisposable
{
private bool _isDisposed;
public bool Keep { get; set; }
public string Path { get; private set; }
public TemporaryFile() : this(false)
{
}
public TemporaryFile(bool shortLived)
{
this.Path = CreateTemporaryFile(shortLived);
}
~TemporaryFile()
{
Dispose(false);
}
public void Dispose()
{
Dispose(false);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_isDisposed)
{
_isDisposed = true;
if (!this.Keep)
{
TryDelete();
}
}
}
private void TryDelete()
{
try
{
File.Delete(this.Path);
}
catch (IOException)
{
}
catch (UnauthorizedAccessException)
{
}
}
public static string CreateTemporaryFile(bool shortLived)
{
string temporaryFile = System.IO.Path.GetTempFileName();
if (shortLived)
{
// Set the temporary attribute, meaning the file will live
// in memory and will not be written to disk
//
File.SetAttributes(temporaryFile,
File.GetAttributes(temporaryFile) | FileAttributes.Temporary);
}
return temporaryFile;
}
}
Using the new class is easy, just type the following:
using (TemporaryFile temporaryFile = new TemporaryFile())
{
// Use temporary file
}
If you decide, after constructing a TemporaryFile, that you want to prevent it from being deleted, simply set the TemporaryFile.Keep property to true:
using (TemporaryFile temporaryFile = new TemporaryFile())
{
temporaryFile.Keep = true;
}
Absolutely. This way you can ensure cleanup with exceptions present.
You should definitely use Dispose to clean up resources, but make sure you implement the IDisposable interface. You don't want to just add a method named Dispose.
I always make my classes that point to temp files IDisposable, and usually implement a finalizer that calls my dispose method there as well. This seems to be the paradigm suggested by the IDisposable MSDN page.
Related code below:
public void Dispose()
{
Dispose(true);
// This object will be cleaned up by the Dispose method.
// Therefore, you should call GC.SupressFinalize to
// take this object off the finalization queue
// and prevent finalization code for this object
// from executing a second time.
GC.SuppressFinalize(this);
}
// Dispose(bool disposing) executes in two distinct scenarios.
// If disposing equals true, the method has been called directly
// or indirectly by a user's code. Managed and unmanaged resources
// can be disposed.
// If disposing equals false, the method has been called by the
// runtime from inside the finalizer and you should not reference
// other objects. Only unmanaged resources can be disposed.
private void Dispose(bool disposing)
{
// Check to see if Dispose has already been called.
if(!this.disposed)
{
// If disposing equals true, dispose all managed
// and unmanaged resources.
if(disposing)
{
// Dispose managed resources.
}
// Call the appropriate methods to clean up
// unmanaged resources here.
// If disposing is false,
// only the following code is executed.
// Note disposing has been done.
disposed = true;
}
}
// Use C# destructor syntax for finalization code.
// This destructor will run only if the Dispose method
// does not get called.
// It gives your base class the opportunity to finalize.
// Do not provide destructors in types derived from this class.
~MyResource()
{
// Do not re-create Dispose clean-up code here.
// Calling Dispose(false) is optimal in terms of
// readability and maintainability.
Dispose(false);
}
If you wish to re-use your temporary files e.g. open\close\read\write\etc, then clearing them up at the AppDomain unload level can be useful.
This can be used in combination with putting temp files in a well known sub-directory of a temp location and making sure that the directory is deleted on application startup to ensure unclean shut-downs are taken care of.
A basic example of the technique (with exception handling removed around delete for brevity). I use this technique in file-based unit tests where it makes sense and is useful.
public static class TempFileManager
{
private static readonly List<FileInfo> TempFiles = new List<FileInfo>();
private static readonly object SyncObj = new object();
static TempFileManager()
{
AppDomain.CurrentDomain.DomainUnload += CurrentDomainDomainUnload;
}
private static void CurrentDomainDomainUnload(object sender, EventArgs e)
{
TempFiles.FindAll(file => File.Exists(file.FullName)).ForEach(file => file.Delete());
}
public static FileInfo CreateTempFile(bool autoDelete)
{
FileInfo tempFile = new FileInfo(Path.GetTempFileName());
if (autoDelete)
{
lock (SyncObj)
{
TempFiles.Add(tempFile);
}
}
return tempFile;
}
}

Using `using(...)` effectively useless and/or inefficient?

Does the following code render the using(...) function/purpose irrelevant?
Would it cause a deficiency in GC performance?
class Program
{
static Dictionary<string , DisposableClass> Disposables
{
get
{
if (disposables == null)
disposables = new Dictionary<string , DisposableClass>();
return disposables;
}
}
static Dictionary<string , DisposableClass> disposables;
static void Main(string[] args)
{
DisposableClass disposable;
using (disposable = new DisposableClass())
{
// do some work
disposable.Name = "SuperDisposable";
Disposables["uniqueID" + Disposables.Count] = disposable;
}
Console.WriteLine("Output: " + Disposables["uniqueID0"].Name);
Console.ReadLine();
}
}
class DisposableClass : IDisposable
{
internal string Name
{
get { return myName; }
set { myName = value; }
}
private string myName;
public void Dispose( )
{
//throw new NotImplementedException();
}
}
Output: SuperDisposable
My understanding of the using(...) function is to immediately coerce disposal of the DisposableClass. Yet within the code block, we are adding the class to a dictionary collection. My understanding is that a class is inherently a reference type. So my experiment was to see what would happen to the disposable object added to a collection in this manner.
In this case DisposableClass is still quite alive. Classes are a reference type - so my assumption then became that the collection is not simply referencing this type, but indeed holding the class as a value. But, that didn't make sense either.
So what is really going on?
EDIT: modified code with output to prove that the object is not dead, as might be suggested by some answers.
2nd EDIT: what this comes down to as I've gone through some more code is this:
public void Dispose( )
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool dispose)
{
if (!isDisposed)
{
if (dispose)
{
// clean up managed objects
}
// clean up unmanaged objects
isDisposed = true;
}
}
~DisposableClass( )
{ Dispose(false); }
Stepping through the code (had a breakpoint at private void Dispose(bool dispose)), where false is passed to the method, it becomes imperative that resources are properly disposed of here. Regardless, the class is still alive, but you are definitely setting yourself up for exceptions. Answers made me more curious...
Disposing an object does not destroy it; it simply tells it to clean up any unmanaged resources it uses as they are no longer needed. In your example, you're creating a disposable object, assigning to a dictionary, and then just telling it to remove some resources.
The correct scenario for the using statement is when you want to initialize a resource, do something with it, and then destroy it and forget about it; for example:
using (var stream = new FileStream("some-file.txt"))
using (var reader = new StreamReader(stream))
{
Console.Write(reader.ReadToEnd());
}
If you want to retain the object after you've used it, you shouldn't be disposing it, and hence a using statement should not be used.
You should not be using a using block in this case, since you need the object after the block has finished. It is only to be used when there is a clear starting and ending point of the lifetime of the object.
It's important to remember that IDisposable, while a slightly special interface, is an interface nonetheless. When the using block exits, it calls Dispose() on your object. Nothing more. Your reference is still valid and, if your Dispose method does nothing, your object will be completely unaffected. If you don't keep track the disposal and explicitly throw exceptions, then you won't get any exceptions after that point because there is no inherent disposed state in .NET.
The IDisposable interface indicates that a type manages some kind of resource. The Dispose method exists to allow you to dispose of the resources used by an instance without having to wait for garbage-collection to take place and the resources to be freed by a finalizer.
In your example, the dictionary is still containing a reference to the disposable class, but the instance will have been disposed at the end of the using block. Subsequent attempts to call methods on the instance will now likely throw ObjectDisposedException or InvalidOperationException, to indicate the instance is no longer in a "working" state.
Disposing an IDisposable is not to be confused with releasing the memory occupied the instance, or invoking any garbage-collection routines on it. The instance is tracked and managed by the garbage-collector like any other, only to be released when the garbage-collector decides it.

Categories