调试不返回

时间:2017-05-31 18:30:52

标签: c# async-await visual-studio-2017 visual-studio-debugging

我正在使用一个小型WPF桌面实用程序,并且正在使用async / await方法来允许事物并行处理。

但是,我一直在遇到等待异步任务根本不会返回的问题。不会抛出任何异常,如果我在调试器中暂停应用程序,则调用堆栈表示它正在运行"外部代码"由调用异步任务的行调用。 (具体来说,它挂在:我的当前示例中的WindowsBase.dll!System.Windows.Threading.DispatcherSynchronizationContext.Wait(System.IntPtr [] waitHandles,bool waitAll,int millisecondsTimeout)。) 我已经多次看过这个并且解决了这个问题,但是每次我都要添加调试代码以找出停止执行的行。 (相同的代码可能会在几次迭代中执行正常,然后挂起)在等待我自己的异步方法和等待框架异步方法时,同样的问题也发生了。 Stream.CopyToAsync和Stream.ReadAsync)

有没有办法在Visual Studio 2017中查看执行任务?我尝试打开"任务"窗口,但我从来没有得过任何东西,除了"没有要显示的任务" - 可能我没有正确使用那个窗口?

FWIW,我做了很多(数百个)并发后台操作,但没有重叠。主要是Web服务调用,文件系统读取和MD5校验和计算。 async / await是否可以同时执行而不会冻结?或者是等待的最大嵌套?

1 个答案:

答案 0 :(得分:4)

由于同步上下文,这看起来像死锁的经典案例。当您同步等待内部调用await的方法返回的任务时,会发生这种情况。例如:

public void Deadlock()
{
    DoSomething.Wait();
}

public Task DoSomething()
{
    // Some stuff
    await DoSomethingElse();
    // More stuff
}

当在同步上下文内时,await的延续将发布到同一个同步上下文。但是同步上下文的线程正在等待DoSomething().Wait(),因此不可用。我们陷入僵局:

  • 继续正在等待同步上下文的线程可用
  • 同步上下文的线程正在等待任务完成,这将在执行继续时发生

有两种可能的解决办法:

  • 停止同步等待任务
  • 等待时使用.ConfigureAwait(false),以便继续不会发布到同步上下文