ホームページ >バックエンド開発 >C++ >StaTaskScheduler を使用して STA スレッドでブロック操作を安全に実行するにはどうすればよいですか?

StaTaskScheduler を使用して STA スレッドでブロック操作を安全に実行するにはどうすればよいですか?

Susan Sarandon
Susan Sarandonオリジナル
2025-01-11 10:47:42640ブラウズ

How Can I Safely Perform Blocking Operations on STA Threads Using StaTaskScheduler?

StaTaskScheduler とメッセージ ポンピング

StaTaskScheduler は ParallelExtensionsExtras ライブラリの一部であり、ユーザーがシングルスレッド アパートメント (STA) スレッドでタスクをスケジュールできるようにします。デフォルトでは、STA スレッドはメッセージをポンプしないため、ブロック操作を実行するときにデッドロックが発生する可能性があります。

デッドロックを回避するには、カスタム同期コンテキストを実装してメッセージを明示的にポンプすることができます。これには、SynchronizationContext クラスの Wait メソッドをオーバーライドしてメッセージ ポンピングを含めることが含まれます。

メッセージポンピングの実装

Wait メソッドでメッセージ ポンピングを実装します:

  1. 保留中のメッセージを確認するには、CoWaitForMultipleHandles の代わりに MsgWaitForMultipleObjectsEx を使用します。
  2. メッセージが検出された場合は、PeekMessage(PM_REMOVE) と DispatchMessage を使用して手動でメッセージをポンプします。
  3. メッセージ ポンプが確実に実行し続けるように、Wait メソッドでハンドルを待ち続けます。

実装例

これは、単純なメッセージ ポンピング ループの実装例です。

<code class="language-c#">var msg = new NativeMethods.MSG();

while (true) {
    nativeResult = NativeMethods.MsgWaitForMultipleObjectsEx(
        count, waitHandles,
        (uint)remainingTimeout,
        QS_MASK,
        NativeMethods.MWMO_INPUTAVAILABLE);

    if (IsNativeWaitSuccessful(count, nativeResult, out managedResult) || WaitHandle.WaitTimeout == managedResult)
        return managedResult;

    if (NativeMethods.PeekMessage(out msg, IntPtr.Zero, 0, 0, NativeMethods.PM_REMOVE)) {
        NativeMethods.TranslateMessage(ref msg);
        NativeMethods.DispatchMessage(ref msg);
    }
    if (hasTimedOut())
        return WaitHandle.WaitTimeout;
}</code>

メッセージ ポンピング機能を備えたカスタム同期コンテキストを実装することにより、ブロック操作を STA スレッド上で安全に実行できるため、デッドロックが回避されます。

以上がStaTaskScheduler を使用して STA スレッドでブロック操作を安全に実行するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。