【发布时间】:2015-01-28 14:38:43
【问题描述】:
当在工作线程上调用的方法需要在 UI 线程上运行代码并等待其完成后再执行其他操作时,可以这样完成:
public int RunOnUi(Func<int> f)
{
int res = Application.Current.Dispatcher.Invoke(f);
return res;
}
但是如果我想用任务来做呢? RunOnUi 方法有没有办法创建在 UI 上启动的任务并将其返回,以便调用者(在工作线程上运行)可以等待它?符合以下签名的内容:public Task<int> StartOnUi(Func<int> f)?
一种方法如下:
public Task<int> RunOnUi(Func<int> f)
{
var task = new Task<int>(f);
task.Start(_scheduler);
return task;
}
在这里,假设 _schduler 拥有 ui TaskScheduler。但我不太喜欢创建“冷”任务并使用 start 方法运行它们。这是“推荐”的方式还是有更优雅的方式?
【问题讨论】:
-
这应该是你很少做的操作。如果你发现自己经常做这样的事情,这表明你的程序设计得不好。在 UI 环境中,您通常应该让大部分代码在 UI 线程中运行,并且只有非常本地化的部分没有 UI 交互被卸载到其他地方并且是
await-ed。每当您觉得需要这样做时,通常表明您应该从操作中提取 UI 代码。 -
你是对的。这是 WPF 应用程序作为 WCF 服务执行的一种特殊情况。每个服务调用都是在一个工作线程上接收的,该线程需要等待在 UI 上执行某些操作的任务(执行更改或读取其中的一些值)。
-
例如WebView2.EnsureCoreWebView2Async 必须在 UI 线程中运行。
标签: c# wpf task-parallel-library task