StaTaskScheduler のデッドロックと STA スレッド メッセージの処理
問題:
レガシー STA COM オブジェクトで StaTaskScheduler
を使用すると、デッドロックが発生する可能性があります。 これは、StaTaskScheduler
内のブロック待機によってメッセージが自動的に送られず、メッセージ ループが停止するために発生します。
解決策 1: カスタム同期コンテキスト
このソリューションには、MsgWaitForMultipleObjectsEx
を使用してメッセージをアクティブに送信するカスタム同期コンテキストが含まれます。 このコンテキストは、Wait
を使用するように WaitHelper
メソッドをオーバーライドし、メッセージ ポンプ ループを組み込みます。 内訳は次のとおりです:
SynchronizationContext.Wait
をオーバーライドします: Wait
呼び出しを SynchronizationContext.WaitHelper
に委任します。MsgWaitForMultipleObjectsEx
を使用して、既に処理されたメッセージを含む保留中のメッセージを検出します。PeekMessage
と DispatchMessage
を使用してメッセージを処理します。解決策 2: ThreadAffinityTaskScheduler
または、StaTaskScheduler
と呼ばれるカスタム ThreadAffinityTaskScheduler
は、組み込みのメッセージ ポンプを提供し、後続の await
操作のスレッド アフィニティを維持します。 プロセスは次のとおりです:
ThreadWithAffinityContext
をインスタンス化します。ThreadWithAffinityContext.Run()
を使用して STA スレッドを起動します。await
以降の継続ではスレッド アフィニティが保持され、カスタム メッセージ ポンプによってメッセージ処理が保証されます。重要な注意事項:
MsgWaitForMultipleObjectsEx
は、すでにキューにあるメッセージを処理するため、メッセージ ポンピングに関しては MsgWaitForMultipleObjects
よりも優れています。ThreadAffinityTaskScheduler
は、STA コンテキスト内でスレッド アフィニティとメッセージ ポンピングの両方が必要な場合に、合理化されたソリューションを提供します。以上がStaTaskScheduler をレガシー STA COM オブジェクトで使用する場合、デッドロックを解決するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。