2009-07-28 102 views
1

當我的進程將要退出時,如何執行一些代碼?我已經試過這樣:C# - 暫停主線程並在進程退出前清理

public static void Main(string[] args) { 

    StartUpMyServer(); 

    AppDomain.CurrentDomain.ProcessExit += delegate(object sender, EventArgs e) 
    { 
     Console.WriteLine("process exiting!"); 
     TellMyServerToStopAcceptingConnectionsAndWaitUntilItsFinishedWithAnyExistingOnes(); 
    }; 

    Thread.Sleep(Timeout.Infinite); 

} 

「過程退出」從不打印,並沒有別的似乎發生。不管它是什麼,它都需要跨平臺(Mono/Linux/OS X/Windows)。

謝謝!

澄清:我可以通過在單獨的線程上啓動和停止服務器並在主線程上輪詢「停止請求」標誌(將在ProcessExit事件處理程序中設置)來完成我想要做的事情每X毫秒。如果可能的話,我想避免使用這種解決方案(額外的線程,cpu週期)。我只想讓主線程暫停,直到進程退出時,它應該告訴服務器停止。可能?

回答

1

我遇到過類似的問題。在我工作的地方,我們有一套庫被我們編寫的每個客戶端應用程序使用,其中包含需要在應用程序退出時執行的清理代碼。 AppDomain.CurrentDomain.ProcessExit非常適合我們,我們必須使用這種方法,因爲我們不能依賴頂層應用程序(運行Program.Main)來顯式調用我們的清理方法,我們也沒有任何控制權(因爲它不是我們的代碼,它屬於使用我們庫的用戶)。

但是,在您的情況下,我不認爲您需要擔心ProcessExit事件觸發您的清理代碼。您正在編寫某種網絡服務器,託管在控制檯應用程序中。如何:

public static void Main(string[] args) 
{ 
    StartUpMyServer(); 

    Console.WriteLine("Press the ESCAPE key to shut down the server."); 
    while (Console.ReadKey(true).Key != ConsoleKey.Escape); 

    ShutDownMyServer(); 
} 

然後,當用戶按Escape鍵,您的服務器將被關閉。爲網絡服務器完成這項工作的最好方法是創建一個Windows服務,它將爲您提供方便的OnStart()和OnStop()方法,您只需在其中包含適當的啓動和關閉代碼,以及Windows服務管理器會爲你調用這些服務。最終,真正的問題是確保你不會永遠睡着......你需要某種方式來指示你的應用程序退出。有很多方法可以做到,這一切都取決於你打算如何運行你的應用程序。

+0

關閉,但我真的需要能夠響應SIGHUP/kill或類似的(以跨平臺的方式)。在我的情況下,這個進程正在被另一個進程啓動和停止,使用System.Diagnostics.Process。 – bvanderveen 2009-08-02 17:30:29

2

Your Thread.Sleep is blocking。你將不得不考慮一個更好的主意。不知道你的服務器如何運行,我不能幫助。

+0

我認爲可能是這種情況。所以主函數退出後主線程中會出現這個事件?要麼...? – bvanderveen 2009-07-28 15:38:56

1

對需要清理的對象執行IDisposable,並在應用程序/服務器關閉時執行Dispose()。一切都是快樂的核桃後,它會自動進行。 :)

+0

在這種情況下唯一需要的「清理」就是在服務器上調用該方法,該方法並沒有進行清理,只是讓它在進程死亡之前完成它所做的工作。 – bvanderveen 2009-07-28 15:43:40