2010-06-10 99 views
6

有沒有一種方法可以監視使用dll的應用程序何時關閉? DLL和應用程序都是C#,Windows Forms也不例外。需要知道應用程序何時關閉

我可以檢查主應用程序何時關閉,但我希望DLL能看到「嘿程序正在關閉並釋放我,我應該在我死前真正做到這一點」。

任何方式來做到這一點?或者我堅持讓應用程序菜「在你死之前做這個」?

+1

你爲什麼需要這個?被管理的DLL通過垃圾回收器自動釋放他們的資源。如果您需要釋放非託管資源,請使用Finalization。 – 2010-06-10 06:51:21

+0

@FractalizerR:使用終結器釋放資源是*不推薦使用,因爲它是不確定的。相反,對象應該實現'IDisposable'。 – 2010-06-10 07:05:01

回答

8

也許AppDomain.ProcessExit事件會適合你?注意(從文檔),雖然以下幾點:

所有 ProcessExit事件處理程序的總執行時間是有限的, 一樣的 所有終結的總執行時間是在工藝的限制 關機。默認值是兩秒。 非託管主機可以通過調用 ICLRPolicyManager::SetTimeout方法 和OPR_ProcessExit枚舉 值來更改此執行時間。

+0

謝謝。我試圖實現它,但是我不認爲這個事件會被調用。不知道是否有一個技巧,使其工作。我做了 AppDomain.CurrentDomain.ProcessExit + = new EventHandler(CurrentDomain_ProcessExit); 並且據我所知,它不會進入CurrentDomain_ProcessExit。我的檢查方式是我想要的代碼,並且只是在Winform消息框到達時顯示它自己。該框應該出現然後消失,或出現然後掛起正常關機的應用程序。但都沒有發生。 :( – Nick 2010-06-10 07:10:24

+0

@Nick:你能分享一下這個實現的細節嗎(例如更新這個問題)我試用了它,並且它按照預期工作 – 2010-06-10 08:25:10

+0

它對我有用(TM),然後是第二個第三次嘗試它停止工作了!? 我正在通過Ctrl-C檢測和優雅退出來完成我的過程 – gatopeich 2012-08-13 15:23:06

1

我們不知道您的代碼的細節,但事實是您的類庫需要知道該進程何時退出可能表明您的應用程序存在設計缺陷。

如果您需要釋放資源或以確定性方式清理其他內容,您應該查看IDisposable界面。如果您的庫公開的類實現了此接口,調用方可以輕鬆地聲明它們不再需要dll功能,請致電Dispose()

也許一個良好的起點,進一步閱讀的是下面的文章:

例如,你可以有下面的類在類庫:

using System; 
using System.IO; 

public class ResourceManager : IDisposable 
{ 
    private Stream _resource; 
    private bool _disposed; 

    public void Dispose() 
    { 
     Dispose(true); 

     // Use SupressFinalize in case a subclass 
     // of this type implements a finalizer. 
     GC.SuppressFinalize(this); 
    } 

    public void Dispose(bool disposing) 
    { 
     if (!_disposed) 
     { 
      if (disposing) 
      { 
       Console.WriteLine("Exiting Process. Cleaning up."); 
       // free resources here 
       if (_resource != null) 
        _resource.Dispose(); 
       Console.WriteLine("Object disposed."); 
      } 

      // Indicate that the instance has been disposed. 
      _resource = null; 
      _disposed = true; 
     } 
    } 
} 

在你的主模塊,那麼你可以通過以下方式使用;該using聲明將保證Dispose()方法被稱爲:

using System; 
using System.Windows.Forms; 

static class Program 
{ 
    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main() 
    { 
     using (ResourceManager manager = new ResourceManager()) 
     { 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
      Application.Run(new Form1()); 
     } 
    } 
} 
+0

它是一個設備驅動程序,因此需要釋放設備,並且如果可能,在應用程序時將其設置回中性狀態因此我需要它在DLL中 當一個程序使用dll時,它可能不會被稱爲一次性的,它可能會離開它,它會被我自己用在我的程序以及其他可能沒有相同編碼的程序 – Nick 2010-06-10 07:12:27

+0

@Nick:釋放未激活的資源(例如您的設備)正是使用情況g'IDisposable()'。 – 2010-06-10 07:26:32

+0

但是,如果人們不使用處置或使用,那麼它不會被稱爲正確? – Nick 2010-06-10 10:41:56

0

AppDomain.ProcessExit將「正常」的工作,但並不guarateed如果一個進程是由任務管理器,例如終止火。因此,如果您的設備驅動程序需要釋放大量資源等,它可能並不理想(也就是說,只有在GC完成之後才能釋放它們)。

請參閱Rick Stahls blog瞭解更多詳情。

0

如果是控制檯應用程序,則需要按照this question中的接受答案進行操作。 最好用IDisposable接口開發。

相關問題