调试不返回的异步任务

Svd*_*ner 0 c# visual-studio-debugging async-await visual-studio-2017

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

但是,我一直遇到一个问题,一个等待已久的异步任务根本就不会返回。没有异常抛出,如果我在调试器中暂停该应用程序,则调用堆栈会说它正在运行“外部代码”,该行由调用异步任务的行调用。(具体来说,它挂在:WindowsBase.dll!System.Windows.Threading.DispatcherSynchronizationContext.Wait(System.IntPtr [] waitHandles,bool waitAll,int millisecondsTimeout)。)可以解决此问题,但是每次必须添加调试代码来确定停止执行的行。(相同的代码可能多次执行都可以正常执行,然后挂起)在等待我自己的异步方法和等待框架异步方法(例如,EG Stream.CopyToAsync和Stream.ReadAsync)上都发生了相同的问题)

有没有办法研究在Visual Studio 2017中执行任务?我尝试打开“任务”窗口,但是除了“没有要显示的任务”之外,我什么都没得到-可能是我没有正确使用该窗口?

FWIW,我正在做很多(数百)并发后台操作,但是没有一个重叠。通常是Web服务调用,文件系统读取和MD5校验和计算。异步/等待是否可以在不冻结的情况下同时执行限制?还是最大的等待嵌套?

Kev*_*sse 5

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

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

public Task DoSomething()
{
    // Some stuff
    await DoSomethingElse();
    // More stuff
}
Run Code Online (Sandbox Code Playgroud)

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

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

有两种可能的解决方法:

  • 停止同步等待任务
  • .ConfigureAwait(false)在等待时使用,这样继续操作就不会发布到同步上下文中