Rumah > pembangunan bahagian belakang > C++ > Bagaimana untuk Menyelesaikan Kebuntuan dalam Benang STA Menggunakan StaTaskScheduler dan BlockingCollection?

Bagaimana untuk Menyelesaikan Kebuntuan dalam Benang STA Menggunakan StaTaskScheduler dan BlockingCollection?

Linda Hamilton
Lepaskan: 2025-01-11 10:33:44
asal
162 orang telah melayarinya

How to Resolve Deadlocks in STA Threads Using StaTaskScheduler and BlockingCollection?

StaTaskScheduler dan mesej utas STA mengepam

Soalan:

Kebuntuan berlaku apabila menggunakan StaTaskScheduler dan BlockingCollection pada utas STA kerana kekurangan pengepaman mesej.

Penyelesaian:

Gunakan MsgWaitForMultipleObjectsEx bukannya CoWaitForMultipleHandles untuk melaksanakan konteks penyegerakan tersuai dengan keupayaan mengepam mesej.

Arahan langkah demi langkah:

  1. Fahami isu ini: Penjadual Tugas STA tidak mengepam mesej secara automatik pada urutan STA.
  2. Punca yang dikenal pasti: Operasi penyekatan yang dilakukan oleh BlockingCollection tidak mengepam mesej.
  3. Cipta konteks penyegerakan tersuai: Gantikan SynchronizationContext.Wait untuk menggunakan MsgWaitForMultipleObjectsEx untuk melaksanakan pengepaman mesej dan melihat/menghantar mesej.
  4. Pasang konteks penyegerakan tersuai: Pasang konteks penyegerakan tersuai pada setiap urutan STA yang dibuat oleh StaTaskScheduler.
  5. Gunakan konteks penyegerakan tersuai: Gunakan StaTaskScheduler dengan konteks penyegerakan tersuai untuk menjadualkan tugas bagi memastikan pengepaman mesej.

Arahan pelaksanaan:

  • Kesan mesej masuk menggunakan MWMO_INPUTAVAILABLE dengan bendera MsgWaitForMultipleObjectsEx.
  • Pam mesej secara manual dengan memanggil Wait dan PeekMessage(PM_REMOVE) dalam kaedah DispatchMessage konteks penyegerakan tersuai.
  • Tangani tamat masa dan keadaan perlumbaan yang berpotensi dengan anggun.

Kelebihan:

  • Menyelesaikan isu kebuntuan dengan memastikan mesej diproses pada urutan STA.
  • Kekalkan persekitaran pelaksanaan STA yang betul untuk objek COM lama.
  • Kekalkan pertalian benang apabila menggunakan kesinambungan tunggu seterusnya.

Kod sampel:

<code class="language-csharp">// 带有消息泵送的自定义同步上下文
class CustomSynchronizationContext : SynchronizationContext
{
    protected override void OnWait(bool unused)
    {
        const uint QS_MASK = 0x0001;
        const uint MWMO_INPUTAVAILABLE = 0x0004;

        var nativeResult = MsgWaitForMultipleObjectsEx(
            0, null, WAIT_INFINITE, QS_MASK, MWMO_INPUTAVAILABLE);

        var msg = new MSG();
        while (true)
        {
            if (nativeResult == WAIT_OBJECT_0)
                break;

            if (PeekMessage(out msg, IntPtr.Zero, 0, 0, PM_REMOVE))
            {
                TranslateMessage(ref msg);
                DispatchMessage(ref msg);
            }

            nativeResult = MsgWaitForMultipleObjectsEx(0, null, 0, QS_MASK, MWMO_INPUTAVAILABLE);
        }
    }
}

// 使用方法
using (var staThread = new ThreadWithAffinityContext(true, true))
{
    staThread.Run(async () =>
    {
        // 在 STA 线程上安装自定义同步上下文
        SynchronizationContext.SetSynchronizationContext(new CustomSynchronizationContext());

        // 使用消息泵送的 STA 线程代码...
    });
}</code>
Salin selepas log masuk

Atas ialah kandungan terperinci Bagaimana untuk Menyelesaikan Kebuntuan dalam Benang STA Menggunakan StaTaskScheduler dan BlockingCollection?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan