2009-03-24 5 views
8

У меня есть класс, который создает экземпляр COM exe из процесса. КлассC# cleanup неуправляемые ресурсы, когда процесс убит

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 объект, когда программа выполняется нормально. Однако, если я закрываю программу в середине ее выполнения, фреймворк никогда не вызывает код, который освобождает мой неуправляемый объект. Это справедливо. Однако есть ли способ заставить программу очистить себя, даже если ее убили?

EDIT: это не выглядит перспективным с жестким убийством из

:(менеджера задача

ответ

8

Обертывание его в попытке окончательно или с использованием предложения даст вам большую часть пути туда :

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

специфика how your app is being shutdown, однако, будет диктовать какие-либо другие меры, которые вы можете сделать (например, с помощью CriticalFinalizerObject).

Я думаю что консоль приложение, которое закрывается (от маленького х) такая же, как Ctrl-C - в этом случае вы можете subscribe to Console.CancelKeyPress для этого.

Редактировать: Вы также должны ReleaseComObject until it returns <= 0.

5

Ну, одна лучшая практика заключается в использовании using заявления:

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

Это по существу ставит finally блоков для Вы должны иметь операторы using почти каждый раз, когда у вас есть экземпляр IDisposable, который вы берете на себя ответственность за очистку. Однако он не фиксирует ситуацию, когда ваш весь процесс прерывается внезапно. довольно редкий, хотя, и y Возможно, вы не захотите об этом беспокоиться. (Это довольно сложно обойти.) У меня было бы ожидаемое ваш финализатор, который будет вызываться с вашим предыдущим кодом, хотя ..

+0

это также не работает. Серверы COM остаются в живых, если я убиваю процесс в середине используемого блока. – Steve

+0

Как вы убиваете процесс? Вы ввели какие-либо записи в свои блоки блокировки, чтобы узнать, что происходит? –

+0

(Простое закрытие программы с нормальным выключением должно быть прекрасным. Прекращение его из диспетчера задач, скорее всего, будет более неприятным.) Правильно ли работает сервер COM, если вы закрываете программу «обычным» способом? –

Смежные вопросы