StaTaskScheduler 및 STA 스레드 메시지 펌핑
질문:
STA 스레드에서 StaTaskScheduler 및 BlockingCollection을 사용할 때 메시지 펌핑 부족으로 인해 교착 상태가 발생합니다.
해결책:
메시지 펌핑 기능이 있는 사용자 정의 동기화 컨텍스트를 구현하려면 MsgWaitForMultipleObjectsEx
대신 CoWaitForMultipleHandles
을 사용하세요.
단계별 지침:
SynchronizationContext.Wait
을 재정의하여 MsgWaitForMultipleObjectsEx
을 사용하여 메시지 펌핑 및 보기/디스패치를 구현합니다. 구현 지침:
MWMO_INPUTAVAILABLE
플래그와 함께 MsgWaitForMultipleObjectsEx
을 사용하여 수신 메시지를 감지합니다. Wait
메소드에서 PeekMessage(PM_REMOVE)
및 DispatchMessage
을 호출하여 메시지를 수동으로 펌핑합니다. 장점:
샘플 코드:
<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>
위 내용은 StaTaskScheduler 및 BlockingCollection을 사용하여 STA 스레드의 교착 상태를 해결하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!