C# DispatcherOperation。任务立即返回

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.

我有一个WPF应用程序,按下按钮,执行以下代码:

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
将在线程池线程上恢复。不是“跑”。