进程被终止时,C#清理非托管资源

时间:2009-03-24 20:56:23

标签: c# dispose

我有一个实例化进程外的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对象。但是,如果我在执行过程中关闭程序,框架就不会调用释放我的非托管对象的代码。这是公平的。但是,有没有办法迫使程序自行清理,即使它被杀死了?

编辑:从任务管理员的强硬杀戮看起来并不乐观:(

2 个答案:

答案 0 :(得分:8)

在try finally或using子句中包装它会让你大部分时间都在那里:

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

how your app is being shutdown的具体内容将决定您可以采取的其他措施(例如使用CriticalFinalizerObject)。

认为关闭的控制台应用程序(来自小x)与Ctrl-C相同 - 在这种情况下,您可以subscribe to Console.CancelKeyPress

修改:您还应该ReleaseComObject until it returns <= 0

答案 1 :(得分:5)

嗯,最佳做法是使用using语句:

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

这基本上会将finally块放入范围的末尾自动调用dispose。每当你有一个IDisposable实例,你负责清理时,你应该有using个语句。但是,它并不能解决您的整个过程突然中止的情况。这是非常罕见的,你可能不想担心它。 (很难绕过它。)我已经期待你的终结器可以使用之前的代码调用..