How can release excel object with IDisposeable interface - c#

I am writing an excel class and i want to release this unmanaged object automatically.
I'm using IDisposable pattern and write Dispose methods.
Example ;
class MSExcel : IDisposable
{
ApplicationClass excel;
bool disposed;
public MSExcel()
{
disposed = false;
excel = new ApplicationClass();
}
public void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
}
excel.Quit();
disposed = true;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~MSExcel()
{
Dispose(false);
}
}
But i have classical error on exc.Quit().
"COM object that has been separated from its underlying RCW".
Have any my mistake in code?

As explained in my answer to your other related question here, you should not be taking actions on reference types from within your finalizer. You enforce this by making use of the bool disposing parameter of your Disposed(bool) method, as you have done. You pass in true, when Disposed(bool) is called explicitly from the void Dispose() method, and pass in false when called from your finalizer, which you have also done.
However, you also need to protect your call to excel.Quit() so that it is not called when Disposed(bool) is called via the finalizer. That is, you should only call excel.Quit() when the bool disposing argument is true.
Therefore, the code for your Disposed(bool) method should look as follows:
public void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
excel.Quit();
}
disposed = true;
}
}
Once done, you could make use of your "MSExcel" class as follows:
using (MSExcel msExcel = new MSExcel)
{
// The code calling your 'MSExcel' object goes here.
}
By doing it this way, when your code gets to the closing bracket, "}", of your using statement block, the Dispose method on your 'MSExcel' class will be called automatically, ensuring that excel.Quit() is called deterministically, and not from a finalizer.
Hope this helps...
Mike

Related

Using IDisposable in expression-bodied member [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Will the Garbage Collector call IDisposable.Dispose for me?
I have a Class which has some unmanaged resources. My class implements the IDisposable interface and releases the unmanaged resources in the Dispose() method. Do I have to call the Dispose() method or will it be automatically called somehow? Will the Garbage Collector call it?
Dispose() will not be called automatically. If there is a finalizer it will be called automatically. Implementing IDisposable provides a way for users of your class to release resources early, instead of waiting for the garbage collector.
The preferable way for a client is to use the using statement which handles automatic calling of Dispose() even if there are exceptions.
A proper implementation of IDisposable is:
class MyClass : IDisposable
{
private bool disposed = false;
void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if(!disposed)
{
if(disposing)
{
// Manual release of managed resources.
}
// Release unmanaged resources.
disposed = true;
}
}
~MyClass() { Dispose(false); }
}
If the user of the class calls Dispose() the cleanup takes place directly. If the object is catched by the garbage collector, it calls Dispose(false) to do the cleanup. Please note that when called from the finalizer (the ~MyClass method) managed references may be invalid, so only unmanaged resources can be released.
If you instantiate your object in a using statement, Dispose() is called for you when code exits the using block
using(var myObject = new MyDisposableObject())
{
blah();
} // Dispose() is called here (or whenever the code exits the block)
If you don't use using, then it's up to you (the calling code) to dispose of your object by explicitely calling Dispose().
Also, you (the implementor of MyObject) can add support for a finalizer in case your caller doesn't call Dispose(). More info here.
You will have to call this method manually, maybe (assuming that "MyClass" implements "IDisposable") in a construct like
using(var myclass = new MyClass())
{
// do something with myclass
}
// now 'myclass'is Disposed
In C# 8.0, you can write as below statement:
using var myclass=new MyClass();
and the "myclass" will be disposed automatically at the end of the scope.
The advantage of the using statement (compared to calling Dispose() explicitly) is that Dispose() is called no matter how you exit this block: by running past the end, encountering a return statement or having an exception thrown.
To make sure the resources are correctly disposed, you need to both implement IDisposable and call Dispose in the destructor(finalizer).
class Foo : IDisposable
{
private bool m_disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~Foo()
{
Dispose(false);
}
protected void Dispose(bool disposing)
{
if (!m_disposed)
{
if (disposing)
{
//release managed resources
}
//release unmanaged resources
m_disposed = true;
}
}
}

Why does the recommended dispose pattern adds a disposed field at each level of the hierarchy?

The Dispose pattern is notoriously complicated to get right, especially when we have a hierarchy of classes that needs to dispose things at different levels. The recommended implementation is as follow, took from Implement a Dispose method - Microsoft Docs.
using System;
class BaseClass : IDisposable
{
// To detect redundant calls
private bool _disposed = false;
~BaseClass() => Dispose(false);
// Public implementation of Dispose pattern callable by consumers.
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (_disposed)
{
return;
}
if (disposing)
{
// TODO: dispose managed state (managed objects).
}
// TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
// TODO: set large fields to null.
_disposed = true;
}
}
using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.InteropServices;
class DerivedClass : BaseClass
{
// To detect redundant calls
private bool _disposed = false;
// Instantiate a SafeHandle instance.
private SafeHandle _safeHandle = new SafeFileHandle(IntPtr.Zero, true);
// Protected implementation of Dispose pattern.
protected override void Dispose(bool disposing)
{
if (_disposed)
{
return;
}
if (disposing)
{
// Dispose managed state (managed objects).
_safeHandle?.Dispose();
}
_disposed = true;
// Call base class implementation.
base.Dispose(disposing);
}
}
What I don't get in this implementation is what advantage we have in adding a _disposed field at each level of the hierarchy? Instead, we could take care of the _disposed only in the top level of the hierarchy (the one implementing directly IDisposable and not care about it in the derived classes.
Something like this:
using System;
class BaseClass : IDisposable
{
// To detect redundant calls
private bool _disposed = false;
~BaseClass()
{
if (_disposed)
{
return;
}
Dispose(false);
_disposed = true;
}
// Public implementation of Dispose pattern callable by consumers.
public void Dispose()
{
if (_disposed)
{
return;
}
Dispose(true);
GC.SuppressFinalize(this);
_disposed = true;
}
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// TODO: dispose managed state (managed objects).
}
// TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
// TODO: set large fields to null.
}
}
using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.InteropServices;
class DerivedClass : BaseClass
{
// Instantiate a SafeHandle instance.
private SafeHandle _safeHandle = new SafeFileHandle(IntPtr.Zero, true);
// Protected implementation of Dispose pattern.
protected override void Dispose(bool disposing)
{
if (disposing)
{
// Dispose managed state (managed objects).
_safeHandle?.Dispose();
}
// Call base class implementation.
base.Dispose(disposing);
}
}
This is such a widely used code sample that there must certainly be a good reason for it to be implemented with the repeated _disposed at each level, but I just can't find any.
It's a tiny bit more code in the base class, but less to worry about in the derived class, and some repeated information removed.
What else am I missing?
Edit:
As #InBetween correctly says that one drawback of my implementation is that if you'd need to check if your object is disposed in one method of the derived class you won't be able to check it. Let's correct that issue by making it a protected property with a private set.
using System;
class BaseClass : IDisposable
{
// To detect redundant calls
protected bool Disposed { get; private set; } = false;
~BaseClass()
{
if (Disposed)
{
return;
}
Dispose(false);
Disposed = true;
}
// Public implementation of Dispose pattern callable by consumers.
public void Dispose()
{
if (Disposed)
{
return;
}
Dispose(true);
GC.SuppressFinalize(this);
Disposed = true;
}
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// TODO: dispose managed state (managed objects).
}
// TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
// TODO: set large fields to null.
}
}
using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.InteropServices;
class DerivedClass : BaseClass
{
// Instantiate a SafeHandle instance.
private SafeHandle _safeHandle = new SafeFileHandle(IntPtr.Zero, true);
public void DoSomething()
{
if(Disposed)
{
throw new ObjectDisposedException("Cannot access disposed resource");
}
}
// Protected implementation of Dispose pattern.
protected override void Dispose(bool disposing)
{
if (disposing)
{
// Dispose managed state (managed objects).
_safeHandle?.Dispose();
}
// Call base class implementation.
base.Dispose(disposing);
}
}
If you are inheriting from a disposable class, one of two conditions must be true.
Your subcless does not introduce a new disposable resource. In this case you don't need to override Dispose and the question is moot.
Your subclass introduces a new disposable resource. In this case, you're going to override Dispose, insert your own disposal code, then call base.Dispose. The _disposed flag is there to help you remember to prevent your disposal code from executing twice.
You certainly can remove _disposed if you want. But you probably do not care much about the base class' _disposed flag, if it even has one. It worries about what it is disposing, and you worry about yours.
The reason is simple. In your implementation you cant use _disposed in the derived type to check if any method is invoked when the object is already disposed and take the necessary actions. In your implementation you'd need to create your own redundant flag isDisposed which defeats the purpose; you already have one "for free" from the pattern itself following the guidelines.
A case could be made though about making _disposed protected.

Make sure that dispose method is always called [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Will the Garbage Collector call IDisposable.Dispose for me?
I have a Class which has some unmanaged resources. My class implements the IDisposable interface and releases the unmanaged resources in the Dispose() method. Do I have to call the Dispose() method or will it be automatically called somehow? Will the Garbage Collector call it?
Dispose() will not be called automatically. If there is a finalizer it will be called automatically. Implementing IDisposable provides a way for users of your class to release resources early, instead of waiting for the garbage collector.
The preferable way for a client is to use the using statement which handles automatic calling of Dispose() even if there are exceptions.
A proper implementation of IDisposable is:
class MyClass : IDisposable
{
private bool disposed = false;
void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if(!disposed)
{
if(disposing)
{
// Manual release of managed resources.
}
// Release unmanaged resources.
disposed = true;
}
}
~MyClass() { Dispose(false); }
}
If the user of the class calls Dispose() the cleanup takes place directly. If the object is catched by the garbage collector, it calls Dispose(false) to do the cleanup. Please note that when called from the finalizer (the ~MyClass method) managed references may be invalid, so only unmanaged resources can be released.
If you instantiate your object in a using statement, Dispose() is called for you when code exits the using block
using(var myObject = new MyDisposableObject())
{
blah();
} // Dispose() is called here (or whenever the code exits the block)
If you don't use using, then it's up to you (the calling code) to dispose of your object by explicitely calling Dispose().
Also, you (the implementor of MyObject) can add support for a finalizer in case your caller doesn't call Dispose(). More info here.
You will have to call this method manually, maybe (assuming that "MyClass" implements "IDisposable") in a construct like
using(var myclass = new MyClass())
{
// do something with myclass
}
// now 'myclass'is Disposed
In C# 8.0, you can write as below statement:
using var myclass=new MyClass();
and the "myclass" will be disposed automatically at the end of the scope.
The advantage of the using statement (compared to calling Dispose() explicitly) is that Dispose() is called no matter how you exit this block: by running past the end, encountering a return statement or having an exception thrown.
To make sure the resources are correctly disposed, you need to both implement IDisposable and call Dispose in the destructor(finalizer).
class Foo : IDisposable
{
private bool m_disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~Foo()
{
Dispose(false);
}
protected void Dispose(bool disposing)
{
if (!m_disposed)
{
if (disposing)
{
//release managed resources
}
//release unmanaged resources
m_disposed = true;
}
}
}

Writing to test that Objects have been properly disposed

What's a good way of writing a test to check that the dispose method of the IDisposable interface is properly releasing unmanaged resources after it is called?
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing)
{
// Free any other managed objects here.
}
// Free any unmanaged objects here
theUnmanagedResource.Dispose();
disposed = true;
}
I was thinking I could check if disposed is false after, but it doesn't guarantee that resources are managed.
Another way is setting theUnmanagedResource = null after theUnmanagedResources.Dispose() and check if it is null after in the test cases. But from other posts, they state setting disposed resources to null after is not a good : Setting Objects to Null/Nothing after use in .NET
As described here, you could check if IDispose.Dispose was called directly(object disposed properly), then bool disposing will be true in a virtual void Dispose(bool disposing):
using System;
class BaseClass : IDisposable
{
// Flag: Has Dispose already been called?
bool disposed = false;
// Public implementation of Dispose pattern callable by consumers.
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing) {
// Free any other managed objects here.
//
}
// Free any unmanaged objects here.
//
disposed = true;
}
~BaseClass()
{
Dispose(false);
}
}

Implementing IDisposable correctly

In my classes I implement IDisposable as follows:
public class User : IDisposable
{
public int id { get; protected set; }
public string name { get; protected set; }
public string pass { get; protected set; }
public User(int UserID)
{
id = UserID;
}
public User(string Username, string Password)
{
name = Username;
pass = Password;
}
// Other functions go here...
public void Dispose()
{
// Clear all property values that maybe have been set
// when the class was instantiated
id = 0;
name = String.Empty;
pass = String.Empty;
}
}
In VS2012, my Code Analysis says to implement IDisposable correctly, but I'm not sure what I've done wrong here.
The exact text is as follows:
CA1063 Implement IDisposable correctly Provide an overridable implementation of Dispose(bool) on 'User' or mark the type as sealed. A call to Dispose(false) should only clean up native resources. A call to Dispose(true) should clean up both managed and native resources. stman User.cs 10
For reference: CA1063: Implement IDisposable correctly
I've read through this page, but I'm afraid I don't really understand what needs to be done here.
If anyone can explain in more layman's terms what the problem is and/or how IDisposable should be implemented, that will really help!
This would be the correct implementation, although I don't see anything you need to dispose in the code you posted. You only need to implement IDisposable when:
You have unmanaged resources
You're holding on to references of things that are themselves disposable.
Nothing in the code you posted needs to be disposed.
public class User : IDisposable
{
public int id { get; protected set; }
public string name { get; protected set; }
public string pass { get; protected set; }
public User(int userID)
{
id = userID;
}
public User(string Username, string Password)
{
name = Username;
pass = Password;
}
// Other functions go here...
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// free managed resources
}
// free native resources if there are any.
}
}
First of all, you don't need to "clean up" strings and ints - they will be taken care of automatically by the garbage collector. The only thing that needs to be cleaned up in Dispose are unmanaged resources or managed recources that implement IDisposable.
However, assuming this is just a learning exercise, the recommended way to implement IDisposable is to add a "safety catch" to ensure that any resources aren't disposed of twice:
public void Dispose()
{
Dispose(true);
// Use SupressFinalize in case a subclass
// of this type implements a finalizer.
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
// Clear all property values that maybe have been set
// when the class was instantiated
id = 0;
name = String.Empty;
pass = String.Empty;
}
// Indicate that the instance has been disposed.
_disposed = true;
}
}
The following example shows the general best practice to implement IDisposable interface. Reference
Keep in mind that you need a destructor(finalizer) only if you have unmanaged resources in your class. And if you add a destructor you should suppress Finalization in the Dispose, otherwise it will cause your objects resides in memory longer that it should (Note: Read how Finalization works). Below example elaborate all above.
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.
}
}
IDisposable exists to provide a means for you to clean up unmanaged resources that won't be cleaned up automatically by the Garbage Collector.
All of the resources that you are "cleaning up" are managed resources, and as such your Dispose method is accomplishing nothing. Your class shouldn't implement IDisposable at all. The Garbage Collector will take care of all of those fields just fine on its own.
You need to use the Disposable Pattern like this:
private bool _disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
// Dispose any managed objects
// ...
}
// Now disposed of any unmanaged objects
// ...
_disposed = true;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// Destructor
~YourClassName()
{
Dispose(false);
}
You have no need to do your User class being IDisposable since the class doesn't acquire any non-managed resources (file, database connection, etc.). Usually, we mark classes as
IDisposable if they have at least one IDisposable field or/and property.
When implementing IDisposable, better put it according Microsoft typical scheme:
public class User: IDisposable {
...
protected virtual void Dispose(Boolean disposing) {
if (disposing) {
// There's no need to set zero empty values to fields
// id = 0;
// name = String.Empty;
// pass = String.Empty;
//TODO: free your true resources here (usually IDisposable fields)
}
}
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
}
Idisposable is implement whenever you want a deterministic (confirmed) garbage collection.
class Users : IDisposable
{
~Users()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
// This method will remove current object from garbage collector's queue
// and stop calling finilize method twice
}
public void Dispose(bool disposer)
{
if (disposer)
{
// dispose the managed objects
}
// dispose the unmanaged objects
}
}
When creating and using the Users class use "using" block to avoid explicitly calling dispose method:
using (Users _user = new Users())
{
// do user related work
}
end of the using block created Users object will be disposed by implicit invoke of dispose method.
I see a lot of examples of the Microsoft Dispose pattern which is really an anti-pattern. As many have pointed out the code in the question does not require IDisposable at all. But if you where going to implement it please don't use the Microsoft pattern. Better answer would be following the suggestions in this article:
https://www.codeproject.com/Articles/29534/IDisposable-What-Your-Mother-Never-Told-You-About
The only other thing that would likely be helpful is suppressing that code analysis warning... https://learn.microsoft.com/en-us/visualstudio/code-quality/in-source-suppression-overview?view=vs-2017

Categories