在UI线程上创建和启动任务
当一个在工作线程上调用的方法需要在UI线程上运行代码并在执行其他操作之前等待它完成时,可以这样做:
public int RunOnUi(Func f) { int res = Application.Current.Dispatcher.Invoke(f); return res; }
但是,如果我想用任务做什么呢? 有没有办法让RunOnUi方法创建一个在UI上启动并返回它的任务,以便调用者(在工作线程上运行)可以等待它? 适合以下签名的东西: public Task StartOnUi(Func f)
?
一种方法如下:
public Task RunOnUi(Func f) { var task = new Task(f); task.Start(_scheduler); return task; }
这里,假设_schduler
持有ui TaskScheduler
。 但是我不太习惯于创建“冷”任务并使用start方法来运行它们。 这是“推荐”的方式还是有更优雅的方式来做到这一点?
只需使用InvokeAsync
而不是Invoke
然后返回函数返回的DispatcherOperation
的Task
。
//Coding conventions say async functions should end with the word Async. public Task RunOnUiAsync(Func f) { var dispatcherOperation = Application.Current.Dispatcher.InvokeAsync(f); return dispatcherOperation.Task; }
如果您无法访问.NET 4.5,则会更复杂一些。 您将需要使用BeginInvoke
和TaskCompletionSource
来包装BeginInvoke
返回的DispaterOperation
上述就是C#学习教程:在UI线程上创建和启动任务分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
public Task RunOnUi(Func f) { var operation = Application.Current.Dispatcher.BeginInvoke(f); var tcs = new TaskCompletionSource (); operation.Aborted += (sender, args) => tcs.TrySetException(new SomeExecptionHere()); operation.Completed += (sender, args) => tcs.TrySetResult((int)operation.Result); //The operation may have already finished and this check accounts for //the race condition where neither of the events will ever be called //because the events where raised before you subscribed. var status = operation.Status; if (status == DispatcherOperationStatus.Completed) { tcs.TrySetResult((int)operation.Result); } else if (status == DispatcherOperationStatus.Aborted) { tcs.TrySetException(new SomeExecptionHere()); } return tcs.Task; }
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1301099.html