イベントを発生させるコードを制御しない場合、選択の余地はありません。その短い期間のスレッド プール スレッドの使用を回避する方法はありません。
イベントを発生させるコードを制御する場合は、イベント ハンドラーがすべて 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 モデルのイベントで特定のコンテキストにマーシャリングできるオブジェクト)。SynchronizingObject
null
その一般的なパターンに従うことができます。
具体的な方法はいくつかあります。ワーカー スレッドが最初に作成された時点で値をキャプチャしSynchronizationContext.Current
、それを使用することができます (無効にする必要がある場合、または強制的に有効にする必要がある場合は、ブール値を使用してソース同期コンテキストのキャプチャを無効にすることができます)。
SynchronizationContext
別のオプションは、 、または特定のコンテキストにコードをマーシャリングする他のメカニズムを受け入れるプロパティを持つことです (独自のものを発明したり、デリゲートを使用したりすることができます)。