UI线程上的任务继续

是否有一种“标准”方式来指定任务继续应该在创build初始任务的线程上运行?

目前我有下面的代码 – 它正在工作,但跟踪调度,并创build第二个行动似乎是不必要的开销。

dispatcher = Dispatcher.CurrentDispatcher; Task task = Task.Factory.StartNew(() => { DoLongRunningWork(); }); Task UITask= task.ContinueWith(() => { dispatcher.Invoke(new Action(() => { this.TextBlock1.Text = "Complete"; } }); 

使用TaskScheduler.FromCurrentSynchronizationContext()调用延续:

  Task UITask= task.ContinueWith(() => { this.TextBlock1.Text = "Complete"; }, TaskScheduler.FromCurrentSynchronizationContext()); 

只有当前执行上下文在UI线程上时,这才是合适的。

与asynchronous你只是做:

 await Task.Run(() => do some stuff); // continue doing stuff on the same context as before. // while it is the default it is nice to be explicit about it with: await Task.Run(() => do some stuff).ConfigureAwait(true); 

然而:

 await Task.Run(() => do some stuff).ConfigureAwait(false); // continue doing stuff on the same thread as the task finished on. 

如果你有一个返回值,你需要发送到用户界面,你可以使用这样的通用版本:

这是从MVVM ViewModel调用我的情况。

 var updateManifest = Task<ShippingManifest>.Run(() => { Thread.Sleep(5000); // prove it's really working! // GenerateManifest calls service and returns 'ShippingManifest' object return GenerateManifest(); }) .ContinueWith(manifest => { // MVVM property this.ShippingManifest = manifest.Result; // or if you are not using MVVM... // txtShippingManifest.Text = manifest.Result.ToString(); System.Diagnostics.Debug.WriteLine("UI manifest updated - " + DateTime.Now); }, TaskScheduler.FromCurrentSynchronizationContext()); 

我只是想添加这个版本,因为这是一个有用的线程,我认为这是一个非常简单的实现。 如果multithreading应用程序,我已经多次使用这个types:

  Task.Factory.StartNew(() => { DoLongRunningWork(); Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => { txt.Text = "Complete"; })); }); 

写你的代码( 但使用ContinueWith是一个很好的做法,不要担心运行时不必要的开销

  Task task = Task.Factory.StartNew(() => { DoLongRunningWork(); Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => { this.TextBlock1.Text = "Complete"; } }); 

Dispatcher代码放在finally块中,如果你想确保这个运行的话。

尝试避免使用 TaskScheduler.FromCurrentSynchronizationContext()因为您的UI Thread可能被当前Thread阻塞。