我有一个类来实例化一个COM exe进程.这堂课是
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;
}
}
Run Code Online (Sandbox Code Playgroud)
我把它称之为如下
static void Main(string[] args)
{
MyComObject test = new MyComObject();
MyComObject test2 = new MyComObject();
//Do stuff
test.Dispose();
test2.Dispose();
Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)
现在,这会在程序正常执行时清理我的COM对象.但是,如果我在执行过程中关闭程序,框架就不会调用释放我的非托管对象的代码.这是公平的.但是,有没有办法迫使程序自行清理,即使它被杀死了?
编辑:从任务管理员的硬杀,它看起来并不乐观:(
在最后尝试或使用子句包装它将使你在那里的大部分方式:
using (MyComObject test = new MyComObject())
using (MyComObject test2 = new MyComObject()) {
// do stuff
}
Console.ReadLine();
Run Code Online (Sandbox Code Playgroud)
但是,关闭应用程序的具体细节将决定您可以执行的任何其他措施(例如使用CriticalFinalizerObject).
我认为关闭的控制台应用程序(从小x开始)与Ctrl-C相同 - 在这种情况下,您可以订阅Console.CancelKeyPress.
编辑:您还应该使用ReleaseComObject,直到它返回<= 0.
嗯,最好的做法是使用using语句:
using (MyComObject test = new MyComObject())
using (MyComObject test2 = new MyComObject())
{
//Do stuff
}
Run Code Online (Sandbox Code Playgroud)
这实际上是finally在块的末尾自动调用块来调用dispose.你应该有using语句几乎只要你有你承担清理责任IDisposable的实例.但是,它并不能解决您的整个过程突然中止的情况.这是非常罕见的,你可能不想担心它.(这很难绕过它.)我已经预料到你的终结器会被你以前的代码调用,但是...