StaTaskScheduler と STA スレッドでのメッセージ ポンピング: 詳細
Parallel Extensions Extras のコンポーネントである StaTaskScheduler は、MTA スレッドと STA スレッドの両方でのタスク スケジューリングを目的としています。 そのドキュメントでは、STA スレッドで TPL 操作をブロックすると、デッドロックを防ぐためにメッセージ ポンプ メカニズムが利用されることが暗示されていますが、常にそうであるとは限りません。
特に、従来の STA COM オブジェクトを操作する場合、BlockingCollection<Task>
内のブロック操作がメッセージ ポンピングのトリガーに失敗することがよくあります。この省略により、STA スレッドで実行するとデッドロックが発生する可能性があります。
より堅牢な解決策は、カスタム同期コンテキストを使用することです。
カスタム同期コンテキストの作成:
SynchronizationContext.Wait
メソッドをオーバーライドして、メッセージ ポンピングを明示的に管理します。MsgWaitForMultipleObjectsEx
フラグを使用して MWMO_INPUTAVAILABLE
を活用します。これにより、シグナル後のメッセージを無期限にブロックすることなく取得できるようになります。SynchronizationContext.Wait
実装内でメッセージを手動で汲み上げてディスパッチします。ThreadAffinityTaskScheduler
の例は、複数の await
継続にわたって STA COM オブジェクトのスレッド アフィニティを維持しながら、このデッドロックの問題に対処するソリューションを示しています。 この実装により、適切な WM_TEST
メッセージ ポンピングが保証され、メッセージ キュー内のデッドロックが防止されます。
以上がStaTaskScheduler を STA スレッドおよび従来の COM オブジェクトとともに安全に使用してデッドロックを回避するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。