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
阻塞。