UIスレッドがWaitHandleまたは他のスレッドプリミティブで待機している間にすべてのWindowsメッセージを処理する方法はありますか?
私は、それが非常に厄介な再入可能性の問題を引き起こす可能性があることを認識しています。とにかくやりたいです。
編集:待機は、UIスレッドで実行する必要がある複雑な関数の途中で発生します。したがって、待機をバックグラウンドスレッドに移動することはできません。(関数を2つに分割すると、複雑で保守不可能な混乱が発生します)
UIスレッドがWaitHandleまたは他のスレッドプリミティブで待機している間にすべてのWindowsメッセージを処理する方法はありますか?
私は、それが非常に厄介な再入可能性の問題を引き起こす可能性があることを認識しています。とにかくやりたいです。
編集:待機は、UIスレッドで実行する必要がある複雑な関数の途中で発生します。したがって、待機をバックグラウンドスレッドに移動することはできません。(関数を2つに分割すると、複雑で保守不可能な混乱が発生します)
「分割できない複雑な関数」全体を別のバックグラウンドスレッドで実行し、必要な場合にのみGUIにレポートするようにします(コントロールでInvoke / BeginInvokeメソッドを使用) 。
より拡張されたバージョンでは、UIに依存せず、単体テストが容易な非UIコントローラーで複雑な関数を実行する必要があります。UIにコールバックし、UIに結果を表示するには、UIを使用して、コントローラーによって使用可能にされたイベントをサブスクライブすることで簡単にアクセスできます。
待機を行うために別のスレッドを生成し、適切な時点でメッセージ(またはその他)を介してUIスレッドに通知するようにしないのはなぜですか?
これは、ブロッキングイベント中にUIスレッドメッセージを処理できるようにするための通常のアプローチです。
編集:わかりました-そのアプリロジックロジックがUIコードに組み込まれています。そうですね、これは本当に設計上の問題です。長期的には、その機能をUIから自己完結型のオブジェクトに分割し、何らかのメカニズムを使用してワーカーからUIとステータスを通信する方がよいでしょう。
UIコードをUIに集中させるという利点に加えて、これにより、ロジックコードを個別に単体テストできます。
C# についてはわかりませんが、プレーンな Win32 プログラミングでは、実際の待機に MsgWaitFor...() 関数の 1 つを使用できます。メッセージキューにメッセージが存在するとき、および待機中のオブジェクトがシグナル状態になったときに通知します。メッセージが存在すると報告された場合は、GetMessage()、TranslateMessage()、および DispatchMessage() を呼び出してメッセージを処理し、待機に戻ることができます。
通常、待機条件を別のスレッドに置くことをお勧めします。
ただし、そうは言っても、いつでもApplication.DoEventsを呼び出して、待機ハンドルで「待機」している間を含め、いつでもメッセージ ポンプを処理できます (単にタイムアウトする、イベントを実行する、タイムアウトで待機するなど、「通過」するまで)。待機ハンドル)。