共用方式為


asynchronousThreadAbort MDA

當執行緒嘗試對另一個執行緒引入非同步中止時,asynchronousThreadAbort Managed 偵錯助理 (MDA) 就會啟動。 同步執行緒中止並不會啟動 asynchronousThreadAbort MDA。

症狀

當主應用程式執行緒中止時,應用程式會損毀,並且出現未處理的 ThreadAbortException。 如果當時要繼續執行應用程式,可能會出現比應用程式損毀更糟的結果,甚至還會造成資料損毀。

原本該自動進行的作業,很可能在部分完成後遭到中斷,使得應用程式資料處於無法預期的狀態。 ThreadAbortException 可以從程式碼執行中似乎是隨機點產生,這些通常預期都不會引發例外狀況。 程式碼可能無法處理這種例外狀況,因而造成損毀。

由於這個問題原有的隨機性,症狀可能會有很大的不同。

原因

一個執行緒中的程式碼呼叫了目標執行緒上的 Thread.Abort 方法,造成非同步執行緒中止。 由於對 Abort 發出呼叫的程式碼,不是在中止作業目標 (Target) 的執行緒上,因此,執行緒中止是非同步的。 同步執行緒中止應該不會造成問題,因為執行 Abort 的程式碼,應該已經只在應用程式狀態一致的安全檢查點上執行過。

由於非同步執行緒中止是在目標執行緒執行中的不可預期點進行,因而出現問題。 若要避免發生這種情形,請撰寫程式碼,並在可能以這種方式中止的執行緒上執行該程式碼,以便在程式碼的幾乎每一行處理 ThreadAbortException,讓應用程式資料能夠回到一致的狀態。 期待在撰寫程式碼時會設想這個問題,或是撰寫出能夠防護各種可能情況的程式碼,都是不切實際的。

呼叫進入 Unmanaged 程式碼和 finally 區塊,並不會非同步地中止,而是會立即從這些分類的其中一個分類中結束。

由於本問題原有的隨機性,可能會難以判定原因。

解決方式

避免需要使用非同步執行緒中止的程式碼設計。 有數種處理方法更適合用來中斷不需要呼叫 Abort 的目標執行緒。 最安全的方法就是採用一種機制,例如通用的屬性,對目標執行緒發出信號以要求中斷。 目標執行緒會在特定的安全檢查點檢查信號。 如果注意到已經要求中斷,目標執行緒就會順利地關閉。

對執行階段的影響

這個 MDA 對 CLR 無效。 它只會報告有關非同步執行緒中止的資料。

Output

這個 MDA 會報告執行中止之執行緒的 ID,以及做為中止目標之執行緒的 ID。 由於僅限於非同步中止,因此,這兩者絕對不會相同。

組態

<mdaConfig>
  <assistants>
    <asynchronousThreadAbort />
  </assistants>
</mdaConfig>

範例

要啟動 asynchronousThreadAbort MDA,只需要呼叫個別執行地執行緒上的 Abort。 請考慮如果執行緒的內容啟動函式是一組更為複雜的作業,而那些作業可能會在任意一點因為中止而中斷的後果。

using System.Threading;
void FireMda()
{
    Thread t = new Thread(delegate() { Thread.Sleep(1000); });
    t.Start();
    // The following line activates the MDA.
    t.Abort(); 
    t.Join();
}

請參閱

參考

Thread

概念

診斷 Managed 偵錯助理的錯誤