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

C#进程终止时清理非托管资源,c#,dispose,C#,Dispose,我有一个类实例化进程外的COM exe。这个班是 public class MyComObject:IDisposable { private bool disposed = false; MyMath test; public MyComObject() { test = new MyMath(); } ~MyComObject() { Dispose(false); } public

我有一个类实例化进程外的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对象。但是,如果我在执行过程中关闭程序,框架就不会调用释放我的非托管对象的代码。这很公平。然而,有没有一种方法可以迫使程序在被杀死的情况下进行自我清理


编辑:从taskmanager的硬杀戮来看,它看起来不太有希望:(

好吧,一个最佳实践是使用
语句:

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

这实际上是将
最后
块放入到作用域末尾,以便在作用域末尾自动调用dispose。只要您有负责清理的IDisposable实例,就应该让
使用
语句。但是,它不能修复整个过程突然中止的情况。这是错误的但是,它非常罕见,您可能不想担心它。(很难绕过它。)但是,我希望您的终结器会被以前的代码调用。

将其包装在try finally或using子句中,这将使您在大部分方面都能做到:

using (MyComObject test = new MyComObject())
using (MyComObject test2 = new MyComObject()) {
    // do stuff
}
Console.ReadLine();
不过,的细节将决定您可以采取的任何其他措施(如使用)

我认为(从小x)关闭的控制台应用程序与Ctrl-C是一样的——在这种情况下,你可以使用它


编辑:你也应该释放CaseObjt对象,直到它返回不起作用。如果我在使用块的中间杀死进程,COM服务器仍然存活。你是如何杀死进程的?你有没有在处理块中记录任何日志来查看发生了什么?(只是用正常关闭的方式关闭程序就可以了。从任务管理器终止它可能会更糟糕。)如果以“正常”方式关闭程序,COM服务器是否正常关闭?是的,如果我以正常方式关闭程序,一切都可以正常关闭。从任务管理器或“小x”,我的COM对象没有被清理。事实上,我也遇到了这个问题,即使使用了块…相当令人沮丧。对于控制台应用程序,似乎按下“X”或Ctrl+C'键都会终止执行,而不考虑托管资源(即我的情况下的连接…)