8

我有一个在进程外实例化 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;
    }
}

我称之为如下

static void Main(string[] args)
    {
        MyComObject test = new MyComObject();
        MyComObject test2 = new MyComObject();

        //Do stuff

        test.Dispose();
        test2.Dispose();

        Console.ReadLine();
    }

现在,当程序正常执行时,这会清理我的 COM 对象。但是,如果我在执行过程中关闭程序,则框架不会调用释放我的非托管对象的代码。这很公平。但是,有没有办法强制程序在被杀死的情况下自行清理?

编辑:从任务管理器的硬杀来看,它看起来并不乐观:(

4

2 回答 2

8

将它包装在 try finally 或 using 子句中将使您大部分时间到达那里:

using (MyComObject test = new MyComObject())
using (MyComObject test2 = new MyComObject()) {
    // do stuff
}
Console.ReadLine();

但是,您的应用程序如何关闭的细节将决定您可以采取的任何其他措施(例如使用CriticalFinalizerObject)。

认为关闭(从小 x 开始)的控制台应用程序与 Ctrl-C 相同 - 在这种情况下,您可以为此订阅 Console.CancelKeyPress

编辑:您还应该ReleaseComObject 直到它返回 <= 0

于 2009-03-24T21:11:06.940 回答
5

好吧,一种最佳做法是使用using语句:

using (MyComObject test = new MyComObject())
using (MyComObject test2 = new MyComObject())
{
    //Do stuff
}

这实质上finally是在作用域结束时自动调用 dispose 块。using每当您有负责清理的 IDisposable 实例时,您几乎都应该有语句。但是,它并不能解决您的整个过程突然中止的情况。不过,这种情况非常罕见,您可能不想担心。(很难绕过它。)虽然我希望的终结器会用你以前的代码来调用..

于 2009-03-24T21:02:57.647 回答