Task.Delay永远不会完成

时间:2014-07-02 07:42:46

标签: c# .net task-parallel-library async-await delay

以下代码将永远冻结。

public async Task DoSomethingAsync()
{
    await Task.Delay(2000);
}

private void Button_Click(object sender, RoutedEventArgs e)
{
    DoSomethingAsync().Wait();
    // Task.Delay(2000).Wait();
}

如果我使用注释掉的代码将调用切换到DoSomethingAsync,它的行为符合预期。我怀疑嵌套的等待导致死锁,但我不确定原因,或者如何修复它。

1 个答案:

答案 0 :(得分:28)

假设Button_ClickGUI主题中运行,你手上就会陷入僵局。

在任务上使用Wait时,您将同步阻塞线程,直到任务结束,但任务永远不会结束,因为继续(Task.Delay(2000);的完成)必须在GUI线程上运行同样(在Wait).

上被屏蔽)

您有多种解决方案。使用ConfigureAwait(false)来捕获GUI线程的SynchronizationContext:

public async Task DoSomethingAsync()
{
    await Task.Delay(2000).ConfigureAwait(false);
}

或(我推荐)使用async void事件处理程序(这是async void方法的唯一合适位置):

private async void Button_Click(object sender, RoutedEventArgs e)
{
    await DoSomethingAsync();
}

public async Task DoSomethingAsync()
{
    await Task.Delay(2000);
}