Reputation: 12054
I have a class that instantiates a COM exe out of process. The class is
public class MyComObject:IDisposable
{
private bool disposed = false;
MyMath test;
public MyComObject()
{
test = new MyMath();
}
~MyComObject()
{
Dispose(false);
}
public double GetRandomID()
{
if (test != null)
return test.RandomID();
else
return -1;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (test != null)
{
Marshal.ReleaseComObject(test);
test = null;
}
disposed = true;
}
}
and I call it as follows
static void Main(string[] args)
{
MyComObject test = new MyComObject();
MyComObject test2 = new MyComObject();
//Do stuff
test.Dispose();
test2.Dispose();
Console.ReadLine();
}
now, this cleans up my COM object when the program executes normally. However, if I close the program in the middle of its execution, the framework doesn't ever call the code that releases my unmanaged object. Which is fair enough. However, is there a way to force the program to clean itself up even though its been killed?
EDIT: it doesn't look promising from a hard kill from the taskmanager :(
Upvotes: 8
Views: 6479
Reputation: 85685
Wrapping it in a try finally or using clause will get you most of the way there:
using (MyComObject test = new MyComObject())
using (MyComObject test2 = new MyComObject()) {
// do stuff
}
Console.ReadLine();
The specifics of how your app is being shutdown, though, will dictate any other measures you can do (like using CriticalFinalizerObject).
I think that a console app that gets closed (from the little x) is the same as a Ctrl-C - in which case you can subscribe to Console.CancelKeyPress for that.
Edit: You should also ReleaseComObject until it returns <= 0.
Upvotes: 7
Reputation: 1504122
Well, one best practice is to use using
statements:
using (MyComObject test = new MyComObject())
using (MyComObject test2 = new MyComObject())
{
//Do stuff
}
That essentially puts finally
blocks in to call dispose automatically at the end of the scope. You should have using
statements pretty much whenever you have an instance of IDisposable that you take responsibility for cleaning up. However, it doesn't fix the situation where your whole process is aborted abruptly. That's pretty rare though, and you may not want to worry about it. (It's pretty hard to get round it.) I'd have expected your finalizer to be called with your previous code though..
Upvotes: 4