C# DispatcherOperation。任务立即返回
我有一个WPF应用程序,按下按钮,执行以下代码:C# DispatcherOperation。任务立即返回,c#,wpf,multithreading,dispatcher,C#,Wpf,Multithreading,Dispatcher,我有一个WPF应用程序,按下按钮,执行以下代码: private void ButtonBase_OnClick(object sender, RoutedEventArgs e) { new Thread( async () => { Action lambda = async () => { await Task.
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
new Thread(
async () =>
{
Action lambda = async () =>
{
await Task.Delay(5000);
MessageBox.Show("Lambda done");
};
await this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, lambda).Task;
MessageBox.Show("Dispatch done");
}).Start();
}
DispatcherOperation.Task的
表示:获取表示当前操作的任务。
(它不是任务
tho:/)所以我认为等待这将意味着
MessageBox.Show(“Dispatch done”)代码>仅在lambda完成后执行。然而,事实并非如此。按下按钮后,带有“Dispatch done”(分派完成)文本的消息框将立即显示,带有“Lambda done”(Lambda完成)文本的消息框将在5秒钟后显示,如预期的那样
有人能解释一下吗?我不明白为什么会这样。这行:
Action lambda = async ...
正在创建async void
lambda,而不是async任务
lambda。async void
的一个(许多)问题是没有(简单的)方法来判断它何时完成。出于这个原因,在我的MSDN关于这个主题的文章中
我没有尝试过,但我怀疑Dispatcher.BeginInvoke
只能执行操作
委托(而不是更异步友好的Func
),在这种情况下,最好使用Dispatcher.Invoke
并传递Func
。不过,在我自己的代码中,我完全避免使用Dispatcher
;我发现它鼓励更糟糕的代码。而不是<代码>调度器< /代码>,考虑使用<代码>等待< />代码>和/或<代码>进程< /代码> .非常感谢。因此,我将lambda更改为返回Func,并使用Dispatcher.Invoke
。现在,它可以按预期工作:)所以我考虑了一下并推断出:当它到达等待任务.Delay
时,lambda返回到wpf消息循环,调度程序.Invoke
也会返回,同样,当调度程序.Invoke
被等待时,它会返回到创建的线程吗?为什么线程没有结束?另外,当我用具有相同参数的Dispatcher.InvokeAsync
替换Dispatcher.InvokeAsync
时,即使它现在是异步任务并且正在等待,也会观察到async void的行为:/@emperueRaiman:我认为这很混乱,因为调度器是“异步”执行的这只是一个同步操作。Invoke
之所以有效,是因为我们正在同步执行异步操作。换句话说,BeginInvoke
返回一个仅表示lambda(调用任务)的同步部分的任务Invoke
返回lambda的任务本身,这就是我们想要的InvokeAsync
返回封装在invoke任务中的lambda任务,因此它可以工作,但您必须双击等待
或调用展开
@emperueraiman:线程将结束。外部await
将在线程池线程上运行,而不是在您创建的线程上运行。@emperueraiman:对不起,我的意思是外部await
将在线程池线程上恢复。不是“跑”。