(2011-03-04 10:40:11)
前台線程能阻止應用程序的終結,一直到所有的前台線程終止後,CLR才能關閉應用程序。後台線程又叫守護線程,它被CLR認為是程序執行中可做出犧牲的途 徑,即在任何時候都可能被忽略,因此,如果所有的前台線程終止,當應用程序域卸載時,所有的後台線程也會被自動終止。值得注意的是:前台線程和後台線程並 不等同於主線程和工作線程,默認情況下,通過Thread.Start()方法創建的線程都自動成為前台線程。把線程的IsBackground屬性設為 true就可以將線程配置為後台線程。
只有當所有的前台線程全部執行完畢後,應用程序才能夠退出。而對於後台線程,當應用程序退出的時候,後台線程會被強制終止。
多線程開發--前台與後台線程
最 近在開發一個多線程程序,其中有使用Control.Invoke(Delegate method)方法調用一個委託來操作主線程上的控件。但在關閉程序時,有時會出現System.InvalidOperationException異 常,異常消息是"Invoke or BeginInvoke cannot be called on a control until the window handle has been created". 出現這個問題的原因是Invoke方法需要使用Control所在的主線程來調用參數中的委託, 但此時的主線程已經結束,執行Invoke方法的這個線程卻還在運行,所以要解決這個問題,就需要在主線程結束之前,要其它關聯的線程要全部關閉。
在經過瘋狂Google一陣後,
終於找到一個解決辦法,就是把主線程設為後台線程: Thread.CurrentThread.IsBackground = true;
MSDN中對前後台線程的解釋是: 一個線程或者是後台線程或者是前台線程。後台線程與前台線程類似,區別是後台線程不會防止進程終止。屬於某個進程的所有前台線程都終止後,公共語言運行庫就會結束該進程。所有剩餘的後台線程都會停止且不會完成。通過IsBackground屬性可以改變其設置。
所以當我們把主線程設為後台線程時,主線程要在所有其它線程關閉後才結束,它也就不會比執行Invoke方法的那個線程先結束,所以Invoke方法也就不會執行失敗了。
PS, 更多參考:
ms-help://MS.MSDNQTR.v80.chs/MS.MSDN.v80/MS.VisualStudio.v80.chs/dv_fxadvance/html/cfe0d632-dd35-47e0-91ad-f742a444005e.htm
託管線程或者是後台線程,或者是前台線程。後台線程不會使託管執行環境處於運行狀態,除此之外,後台線程與前台線程是一樣的。一旦所有前台線程在託管進程(其中 .exe 文件是託管程序集)中被停止,系統將停止所有後台線程並關閉。
注意
當運行庫因為進程關閉而停止某個後台線程時,不會在該線程中引發異常。但是,當線 程是因為 System.AppDomain.Unload(System.AppDomain) 方法卸載應用程序域而停止時,將同時在後台和前台線程中引發 ThreadAbortException。
請使用 Thread.IsBackground 屬性確定線程是後台線程還是前台線程,或更改其狀態。通過將其 IsBackground 屬性設置為 true,可在任何時候將線程更改為後台線程。
要點
線程的前台或後台狀態不影響線程中未處理異常的結果。在 .NET Framework 2.0 版中,前台或後台線程中的未處理異常都將導致應用程序終止。請參見託管線程中的異常。
屬於託管線程池的線程(即其 IsThreadPoolThread 屬性為 true 的線程)是後台線程。從非託管代碼進入託管執行環境的所有線程都被標記為後台線程。通過創建並啟動新的 Thread 對象而生成的所有線程都默認為前台線程。
如果使用一個線程監視活動(例如套接字連接),請將其 IsBackground 屬性設置為 true,以便該線程不會阻止進程終止。
**默認情況,在新開啟一個子線程的時候,他是前台線程,只有,將線程的IsBackground屬性設為true;他才是後台線程
*當子線程是前台線程,則主線程結束並不影響其他線程的執行,只有所有前台線程都結束,程序結束
*當子線程是後台線程,則主線程的結束,會導致子線程的強迫結束
(個人理解,這樣設計的原因:因為後台線程一般做的都是需要花費大量時間的工作,如果不這樣設計,主線程已經結束,而後台工作線程還在繼續,第一有可能使程序陷入死循環,第二主線程已經結束,後台線程即時執行完成也已經沒有什麼實際的意義)