18

DispatcherQueueを理解するのに助けが必要だと思います。

新しい作業が到着すると、ディスパッチャキューの先頭に追加され、ディスパッチャが作業項目を処理する場合は、最初から削除されます。

より一般的に言えば、作業がある場合は、キュー内にFIFO方式で格納され、作業が残っていない限り処理されます。

ここでのMSDNドキュメントは、aloopframe:を参照しています。

The Dispatcher processes the work item queue in a loop. The loop is referred to as a frame.

しかし、このコンテキストでのループはどこにありますか?私にとって、ループとは何かを繰り返すものであり、最後に達すると最初からやり直します。

そして、の概念は何frameですか?MSDNのドキュメントによると、フレームはキュー内の作業項目のパンチですか?それが本当なら、静的メソッドはどのようDisptatcher.PushFrame()に使用されるべきですか?

そして、最も興味深い質問は、キューの現在の状態、特にキューにあるアイテムの数を取得する方法があるかどうかです。

以前に呼び出された(したがってDispatcherキューに入れられた)メソッドが実行された後、すぐにキューから削除された場合、または別の期間内部に残った場合、それは保持されますか?

私は知っています、とても多くの質問:-)

4

1 に答える 1

27

を取り巻くドキュメントはほとんどないDispatcherので、内部の仕組みについて知るために少し分解する必要があります。

ディスパッチャは基本的に、アプリケーションの メッセージポンプを回避するための作業を実行するものです。問題の1つは、 Windowsのメッセージループの上にあります。

結果として、アプリケーションDispatcherは1つだけになります。これは、によってアクセス可能なグローバルディスパッチャオブジェクトApplication.Current.Dispatcherです。Dispatcher.CurrentDispatcherドキュメントによると、にアクセスすることで他のディスパッチャが可能です。

現在実行中のスレッドのディスパッチャーを取得し、まだスレッドに関連付けられていない場合は新しいディスパッチャーを作成します。

Runただし、この新しいディスパッチャの呼び出しはブロックされます。

を実行するDispatcher.PushFrameと、内部実行ループがディスパッチャにプッシュされます。これがフレームの一般的な考え方です。DispatcherObjectなどから継承するものはすべてDispatcherFrame、ディスパッチャが現在のものに設定されます。これは、コンストラクターを調べることで確認できます。

private Dispatcher _dispatcher;

protected DispatcherObject()
{
    this._dispatcher = Dispatcher.CurrentDispatcher;
}

もちろん、単純なイベントループを持つだけでは十分ではありません。他の作業を強制的に実行するために、現在のイベントループを破壊する必要がある場合があります。そしてそれがあなたが持っている理由ですDispatcherFrame。これが実際にイベントループを構成するものです。フレームをディスパッチャにプッシュすると、次のようになります。

while (frame.Continue)
        {
            if (!this.GetMessage(ref msg, IntPtr.Zero, 0, 0))
            {
                break;
            }
            this.TranslateAndDispatchMessage(ref msg);
        }

メッセージがTranslateAndDispatchMessage取り出された後、ディスパッチャの優先キューが評価されます。

ディスパッチャでの操作の実行に時間がかかる場合、イベントループが一時的に停止し、シグナリングに応答しないため、アプリケーションが応答を停止しているように見えます。

これは、フレームを使用して、イベントループをすぐに実行できるようにすることでUIを強制的に応答させる記事です。

キューへのアクセスは、そのままではディスパッチャの外でキューの状態を知る方法はありません。これは内部の詳細であり、公開されていないのは合理的です。

于 2012-07-10T18:40:13.917 に答える