これは、WPFプログラムのディスパッチャループにとって不可欠な配管です。 Windows上のすべてのGUIプログラムには1つがあり、それはproducer-consumer problemへの普遍的な解決策です。 OSやその他のプログラムが生成され、WPFプログラムのUIスレッドが消費される場所。 GUIアプリケーションを厳しく要求すると、GUIを実装するライブラリコードは決してスレッドセーフではありません。ここでループを簡単に見ることができます。スレッドセーフなキューがループによって空になっているのを見ることはできません。それはOSに組み込まれています。
ループは、Application.Run()の呼び出しによって開始されます。 WPFアプリケーションでは分かりにくく、App.xamlファイルのほとんどのアプリケーションで自動生成されます。最初の "フレーム"がプッシュされると、ループ内にある限り、アプリは実行を続けます。イベントハンドラにブレークポイントを設定すると、コールスタックデバッガウィンドウに常に表示されます。あなたのアプリのMainWindowを閉じることは、ループが終了する通常の方法です。これによりRun()メソッドが返され、プロセスを終了するUIスレッドが終了します。
ネストされたディスパッチャループが必要なシナリオがいくつかあります。 「モーダルループ」。毎日使用するモーダルループの例は、マウスをクリックしてウィンドウの角にドラッグすることです。すべてのマウスとキーボードの入力がウィンドウのサイズや位置を変更するようになりましたが、通常の方法でUIを操作するために使用されなくなりました。マウスを離すと、そのループが終了します。このディスパッチャループはOSに組み込まれており、WPFでは実行されません。
しかし、WPFはこのようなモーダルループにも使用されています。標準的な例はWindow.ShowDialog()
メソッドです。このメソッドは、ダイアログが閉じられるまで戻りません。 WPFが内部的にPushFrame()を再度呼び出すことで達成されます。デバッガで試してみると、両方のPushFrame呼び出しが[コールスタック]ウィンドウに表示されます。最初のものはShowDialog()が呼び出したもので、2番目はアプリケーションであるものです。Run()が呼び出されました。ダイアログにダイアログが表示されると、さらに多くの情報が得られます。
あまり明白でない例は、UIスレッドでDispatcher.Invoke()を呼び出すことです。呼び出されたメソッドが返るまで返されないメソッド。通常は少しバグですが、それを拒否する理由はありませんでした。警告の言葉は適切かもしれませんが、モーダルループはかなり危険です。彼らには、の再入荷バグが発生した。 DoEvents()メソッドが非常に悪名高いバグです。 ShowDialog()がUI内の他のすべてのウィンドウを無効にする大きな理由です。
https://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.pushframe.aspx – crowchirp
私はドキュメントを読んでいます。私はそれがどのように機能するのか知っていますが、私はこの方法の目的を理解できません。なぜPushFrameメソッドが必要です – LmTinyToon