【问题标题】:Debugging async tasks that don't return调试不返回的异步任务
【发布时间】:2017-05-31 18:30:51
【问题描述】:

我正在开发一个小型 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 是否限制了它可以同时执行的操作而不会冻结?还是等待的最大嵌套?

【问题讨论】:

  • 输出窗口中什么都没有?
  • 您使用的是 Windows 7 吗?它不支持“任务”窗口。也许看看线程窗口,这不太有用,因为异步任务不一定在不同的线程上运行,但您可能会从中获得一些有用的信息。
  • 由于同步上下文,这看起来很像死锁。您是否在某处同步等待任务? (使用task.Resulttask.Wait()
  • @SvdSinner,请同时禁用“工具”->“选项”->“调试”->“常规”下的“使用托管兼容模式”。 social.msdn.microsoft.com/Forums/vstudio/en-US/….
  • @dukedukes 很遗憾,我的工作机器卡在了 Windows 7 上,这就解释了这个问题。

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


【解决方案1】:

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

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

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

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

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

有两种可能的解决方法:

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

【讨论】:

猜你喜欢
  • 2013-04-16
  • 1970-01-01
  • 2015-01-12
  • 2014-10-01
  • 2016-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多