C# 通过调度程序执行的操作(()=>;{})将冻结ui

C# 通过调度程序执行的操作(()=>;{})将冻结ui,c#,async-await,C#,Async Await,我尝试了一个带有和不带的简单异步等待示例。ConfigureAwait(false) 使用.ConfigureAwait(false)可以通过dispatcher更新ui,没有它是不必要的。 这是下面代码中的案例1和案例3-这是有效的,我可以理解它是如何工作的 我的问题是关于案例2,其中我添加了一个-完全不必要的-刷新 操作(()=>{})通过调度程序执行。 这有时会冻结我的ui。尤其是在反复调用eventhandler之后。 有人能解释为什么在案例2中ui会冻结吗 private void T

我尝试了一个带有和不带
的简单异步等待示例。ConfigureAwait(false)

使用
.ConfigureAwait(false)
可以通过dispatcher更新ui,没有它是不必要的。
这是下面代码中的案例1和案例3-这是有效的,我可以理解它是如何工作的

我的问题是关于案例2,其中我添加了一个-完全不必要的-刷新
操作(()=>{})
通过调度程序执行。
这有时会冻结我的ui。尤其是在反复调用eventhandler之后。
有人能解释为什么在案例2中ui会冻结吗

private void Test_Click(object sender, RoutedEventArgs e)
{
    Test();
}

public async void Test()
{
    Print("Start task");

    // Case 1 & 2
    await Task.Delay(2000);
    // Case 3
    await Task.Delay(2000).ConfigureAwait(false);

    Print("Finished task");
}

void Print(string text)
{
    // Case 1 & 2
    Output.Inlines.Add(new Run(text) { Foreground = Brushes.Blue, FontWeight = FontWeights.Bold });
    // Case 2 only
    Output.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background, new Action(() => { }));

    // Case 3
    Output.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background, 
       new Action(() => 
       {  
         Output.Inlines.Add(new Run(text) { Foreground = Brushes.Blue, FontWeight = FontWeights.Bold 
       }); }));
}
这是WPF中的一个bug


它运行一个过滤的
GetMessage()
循环(请参阅),如果该循环是一条卡在队列中不符合过滤器要求的消息,则会运行该循环。

暂停调试器并查看堆栈跟踪。暂停UI的不是
操作(()=>{})
。正是
任务.Delay(2000)
没有
配置等待(false)
。由于它被配置为在UI线程上运行,您的UI线程将在未指定的时间挂起2秒。那个未指定的时间就是案例2的运行时间。@RaymondChen:延迟等待着,根本没有冻结。只有在添加了空操作之后,它才会执行。@当它被冻结时,我将无法暂停调试器。从wait返回后的调用堆栈以:恢复异步操作开始。@RaymondChen:No;这仍然是一个异步调用;它只是在UI线程上恢复。进一步看,我的解释是错误的;它实际上并没有过滤任何东西。它仍然是WPF中的一个bug,但我不知道为什么它会挂起。@hvd:是的;我才意识到。知道它为什么会挂起来吗?@SLaks当我看到你的评论时,我意识到你意识到了这一点不,不知道。看起来不像一只虫子:@YuvalItzchakov:但这并不能解释为什么它会被挂起来。