Heim >Backend-Entwicklung >C++ >Wie löst man Deadlocks in STA-Threads mithilfe von StaTaskScheduler und BlockingCollection?
StaTaskScheduler und STA-Thread-Nachrichtenpumpen
Frage:
Bei der Verwendung von StaTaskScheduler und BlockingCollection im STA-Thread kommt es zu einem Deadlock, da keine Nachrichten weitergeleitet werden.
Lösung:
Verwenden Sie MsgWaitForMultipleObjectsEx
anstelle von CoWaitForMultipleHandles
, um einen benutzerdefinierten Synchronisierungskontext mit Funktionen zum Senden von Nachrichten zu implementieren.
Schritt-für-Schritt-Anleitung:
SynchronizationContext.Wait
, um MsgWaitForMultipleObjectsEx
zum Implementieren des Nachrichtenpumpens und zum Anzeigen/Versenden von Nachrichten zu verwenden. Umsetzungshinweise:
MWMO_INPUTAVAILABLE
mit dem Flag MsgWaitForMultipleObjectsEx
. Wait
und PeekMessage(PM_REMOVE)
in der Methode DispatchMessage
des benutzerdefinierten Synchronisierungskontexts aufrufen. Vorteile:
Beispielcode:
<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>
Das obige ist der detaillierte Inhalt vonWie löst man Deadlocks in STA-Threads mithilfe von StaTaskScheduler und BlockingCollection?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!