共用方式為


dangerousThreadingAPI MDA

更新:2007 年 11 月

Thread.Suspend 方法在目前執行緒以外的執行緒上呼叫時,dangerousThreadingAPI Managed 偵錯助理 (MDA) 就會啟動。

症狀

應用程式沒有回應或一直處於擱置狀態。系統或應用程式資料可能暫時維持在無法預期的狀態,或者甚至會在應用程式關閉後仍然保持這樣的狀態。這些作業並未如預期地完成。

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

原因

某個執行緒遭到使用 Suspend 方法的另一個執行緒非同步暫止。沒有方法可以判斷何時才能安全地暫止另一個執行緒,因為另一個執行緒可能正在進行作業。暫止執行緒可能會造成資料損毀,或是變異中斷。如果使用 Resume 方法讓執行緒處於暫止和無法繼續的狀態,應用程式可能就會一直處於擱置狀態,而且可能損毀應用程式資料。這些方法已經標記為過時。

如果目標 (Target) 執行緒持有同步基元 (Synchronization Primitive),就會在暫止期間繼續持有這些同步基元。這樣會使得另一個執行緒發生死結 (Deadlock),例如執行 Suspend 的執行緒,嘗試對基元取得鎖定時,就可能導致死結。在此情況下,死結也就是問題所在。

解決方式

避免需要使用 SuspendResume 的設計。對於執行緒之間的合作,請使用如 MonitorReaderWriterLockMutex 的同步基元,或是 C# lock 陳述式。如果必須使用這些方法,請減少使用時間,並最小化執行緒在暫止狀態中所執行的程式碼量。

對執行階段的影響

這個 MDA 對 CLR 無效。它只會報告有關危險執行緒作業的資料。

輸出

這個 MDA 會識別出讓它啟動的危險執行緒方法。

組態

<mdaConfig>
  <assistants>
    <dangerousThreadingAPI />
  </assistants>
</mdaConfig>

範例

下列程式碼範例說明對 Suspend 方法的呼叫,該呼叫會造成 dangerousThreadingAPI 啟動。

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

請參閱

概念

診斷 Managed 偵錯助理的錯誤

參考

Thread

lock 陳述式 (C# 參考)