メインスレッドには、自分のWPF GUIと、時にはメインスレッドで非同期にコードを実行する必要がある1つ以上のバックグラウンドスレッド(たとえば、GUIのステータス更新)が含まれています。WPF GUIスレッドでコードを実行するための好ましい方法は何ですか?
あり、この達成するために二つの方法(私が知っている、多分それ以上)のとおりです。使用してデリゲートを呼び出すことによって、ターゲットスレッドの同期コンテキストからTaskScheduler
を使用してタスクをスケジュールすることによって
- は、と
- ターゲットスレッドからの
Dispatcher
コードで
:
using System.Threading.Tasks;
using System.Threading;
Action mainAction =() => MessageBox.Show(string.Format("Hello from thread {0}", Thread.CurrentThread.ManagedThreadId));
Action backgroundAction;
// Execute in main thread directly (for verifiying the thread ID)
mainAction();
// Execute in main thread via TaskScheduler
var taskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
backgroundAction =() => Task.Factory.StartNew(mainAction, CancellationToken.None, TaskCreationOptions.None, taskScheduler);
Task.Factory.StartNew(backgroundAction);
// Execute in main thread via Dispatcher
var dispatcher = System.Windows.Threading.Dispatcher.CurrentDispatcher;
backgroundAction =() => dispatcher.BeginInvoke(mainAction);
Task.Factory.StartNew(backgroundAction);
例えば、私はすでにTPLをたくさん使うので、私は、TPLベースのバージョンが好きで、それは多くの柔軟性を提供してくれるタスクを待つか、他のタスクと連鎖させるしかし、私が今まで見たWPFコードのほとんどの例では、Dispatcherバリアントが使用されていました。
私はその柔軟性を必要とせず、ターゲットスレッドでいくつかのコードを実行したかったと仮定すると、一方の方法よりも一方の方法を好む理由は何ですか?パフォーマンスに何か影響はありますか?
+1。私は 'FromCurrentSynchronizationContext()'メソッドが存在することさえ知りませんでした! – Cameron
ワンタイム/ワンオフ非同期処理に 'Tasks'を使うことを考えます。しかしながら、 'Dispatcher.Invoke'を使用することは、アプリケーションの長さを実行し、周期的に情報を取得するバックグラウンドスレッドに必要と思われます。 –