dangerousThreadingAPI MDA

dangerousThreadingAPI マネージド デバッグ アシスタント (MDA) は、現在のスレッド以外のスレッドで Thread.Suspend メソッドが呼び出されるとアクティブになります。

現象

アプリケーションが応答しません。 システムまたはアプリケーションのデータが一時的に、またはアプリケーションのシャットダウン後も、予期しない状態のままになっている可能性があります。 一部の操作が予期したとおりに完了していません。

問題に伴うランダム性により、症状は大きく異なる場合があります。

原因

スレッドは、Suspend メソッドを使用する別のスレッドによって非同期に中断されています。 操作途中である可能性がある別のスレッドを安全に中断できるタイミングを判断する方法はありません。 スレッドを中断すると、データの破損やインバリアントの中断が発生することがあります。 スレッドが中断状態になっていて、Resume メソッドを使用して再開されないと、アプリケーションが応答を停止し、アプリケーション データが損害を受けることがあります。 これらのメソッドは不使用とマークされています。

同期プリミティブがターゲット スレッドによって保持されている場合は、中断の間も保持されたままになります。 これにより、Suspend を実行するスレッドなど、別のスレッドがプリミティブのロックを取得しようとすると、デッドロックが発生することがあります。 この場合、問題自体がデッドロックとして現れます。

解決方法

Suspend および Resume を使用する必要のある設計を避けます。 スレッド間の協調では、MonitorReaderWriterLockMutex などの同期プリミティブや、C# の lock ステートメントを使用します。 これらのメソッドを使用する必要がある場合は、時間を短くし、スレッドが中断状態にある間に実行されるコードの量を最小限に留めます。

ランタイムへの影響

この MDA は CLR に影響しません。 危険なスレッド処理操作に関するデータを報告するだけです。

出力

MDA は、アクティブになった原因である危険なスレッド処理メソッドを示します。

構成

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

dangerousThreadingAPI のアクティブ化の原因となる Suspend メソッド呼び出しのコード例を次に示します。

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();  
}  

関連項目