1

BeginInvoke を介して非同期に発生するイベントがあるため、イベント ハンドラーは独自のスレッドプール スレッドを取得します。ただし、イベント ハンドラー内のすべてのコードは UI スレッドにディスパッチされる必要があるため、イベント ハンドラー コード全体が Dispatcher.BeginInvoke ブロック内にあります。これの意味は:

  1. スレッドを開始すると、BeginInvoke でイベントが発生します。
  2. イベント ハンドラー コードを実行するための新しいスレッドプール スレッドが作成されます。
  3. イベント ハンドラーは、ディスパッチャー (Dispatcher.BeginInvoke(...all handler code...) を使用して、コードを非同期で UI スレッドにすぐに投稿します。
  4. temp スレッドプール スレッドは、準すぐに戻ります。これは、UI スレッド ポストを行うためだけに作成されます。

この非常に短期間の中間スレッドプール スレッドの作成を回避するためにこれを再構築する方法はありますか (つまり、ハンドラー コードは UI スレッドで直接実行されるだけです)。

イベントを同期的に発生させたくない(呼び出し)-さまざまなコンテキストで使用されます-ブロックするべきではありません。

4

2 に答える 2

4

Dispatcher.BeginInvokeスレッドプール スレッドを使用する代わりに直接呼び出すことはできますか?

于 2013-02-25T15:04:13.580 に答える
2

イベントを発生させるコードを制御しない場合、選択の余地はありません。その短い期間のスレッド プール スレッドの使用を回避する方法はありません。

イベントを発生させるコードを制御する場合は、イベント ハンドラーがすべて UI スレッドで実行されるようにするオプションがあります。これは確かに可能ですが、そうすべきかどうかについては、じっくりと考える必要があります。特定のイベント ハンドラーでは、UI スレッドで実行することが理にかなっています (例として、UI スレッドでForm実行されるほとんどのイベント) とそうでないものがあります。イベントが UI コントロール上にある場合、おそらく UI スレッドで実行するのが理にかなっています。現時点でUIスレッドから使​​用しているワーカークラスのイベントである場合、UIスレッドでイベントを発生させるのはおそらく悪い考えです(将来、そのワーカーコンテキストを使用する可能性があるため)非 WPF コンテキストで)。

UI スレッドでイベントを発生させたい場合は、簡単です。イベントを発生させる予定のときに既に UI スレッドにいる場合は、同期的に呼び出すだけです。

var eventCopy = MyEvent;
if(eventCopy != null) eventCopy();

イベントを発生させたいときに UI スレッドにいない場合は、上記のコードを呼び出す前に UI スレッドにマーシャリングします。

Dispatcher.BeginInvoke(()=>{ //Or just `Invoke`, if that's appropriate in context
    var eventCopy = MyEvent;
    if(eventCopy != null) eventCopy();
});

編集に基づいて、UI スレッドで常に発生するのではなく、特定のコンテキストに基づいて UI スレッドまたはスレッド プール スレッドで条件付きでイベントを発生させたいようです。

これは可能ですが、それだけの価値があるかどうかを判断する必要があります。

例として、イベントがどのように発生するかを決定できるプロパティをSystem.Timers.Timer持つものを確認できます (スレッド プール、または特定の UI モデルのイベントで特定のコンテキストにマーシャリングできるオブジェクト)。SynchronizingObjectnull

その一般的なパターンに従うことができます。

具体的な方法はいくつかあります。ワーカー スレッドが最初に作成された時点で値をキャプチャしSynchronizationContext.Current、それを使用することができます (無効にする必要がある場合、または強制的に有効にする必要がある場合は、ブール値を使用してソース同期コンテキストのキャプチャを無効にすることができます)。

SynchronizationContext別のオプションは、 、または特定のコンテキストにコードをマーシャリングする他のメカニズムを受け入れるプロパティを持つことです (独自のものを発明したり、デリゲートを使用したりすることができます)。

于 2013-02-25T15:15:16.540 に答える