2012-03-09 36 views
1

ManualResetEventのインスタンスでSetメソッドを呼び出すときに、デッドロックが発生することがあります。私はこれがブロッキング方法であることを示すためにドキュメント内に何かを見つけることができません。何がMREを引き起こす可能性がありますか?EventWaitHandle.Set()が現在のスレッドをブロックする原因は何ですか?

スタックトレース:

[Managed to Native Transition] 
mscorlib.dll!System.Threading.EventWaitHandle.Set() + 0xe bytes 
MyCode.StopAll(bool force) Line 179 + 0xd bytes 
MyCode.CalcCheckThread() Line 250 + 0xb bytes 
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state) + 0x66 bytes 
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x6f bytes 
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x44 bytes 



private static void StopAll(bool force) 
{ 
    if(!force) 
     LogHelper.SendAllCloseState(logger); 

    _forcablyExit = force; 
    _running = false; 
    _stopWait.Set(); // This line appears to be blocking 
} 
+2

コードはどのように見えるのですか? – MoonKnight

+0

私はSet()を呼び出すメソッドを追加しました。他のスレッドのスタックトレースにパターンが見つかりませんでした。 – chilltemp

+0

ブロックするMRE.Setを聞いたことがなかったので、これは非常に奇妙です。コールの後に 'Console.WriteLine'か他の出力を置いて返していないことを確認しましたか? – Tudor

答えて

1

我々は、Microsoftの開発者サポートで私たちの友人の助けを借りて、この問題の原因を突き止めました。

EventWaitHandle.Set()はクリティカルブロックセクションに入り、ネイティブコードがクリティカルブロックに入ってそれを解放しないとブロックできます。これは、私たちが使用している非常に古いサードパーティのライブラリで起こっており、簡単に置き換えたり更新することはできません。

+0

うわー、冗談じゃないの?つまり、完全に管理されたバージョンの 'ManualResetEvent'が必要になります。 'ManualResetEventSlim'は、舞台裏で古いMREを使用しているので動作しません。 –

+0

とにかく 'ManualResetEventSlim'を試してみてください。特定のコードパスのみが存在し、結果として基本的な 'ManualResetEvent'が生成されます。 MRESは後に働くかもしれません。 –

+0

ありがとうございます。残念ながら、これは3.5 SP1であり、MRESは4.0で導入されました。 MREは、メインスレッドに作業を終了してアプリケーションを終了する必要があることを通知するために使用されます。そのような条件の1つは、ネイティブコードが決して戻らない既知の状態です。とにかくこれが致命的であることを考えると、私たちは親アプリケーション(stdout)に、この子アプリケーションがX秒以内に強制終了しなければ強制的に終了する必要がある(taskkill.exe)ように通知しています。醜いハックだが、今日の問題を解決する。 4にアップグレードすると、MRESを念頭に置いておきます。 – chilltemp

関連する問題