如何通过 async/await 找到哪个方法“挂起”?

2024-03-08

在“旧”时代,跟踪哪个方法挂起非常容易:只需转到调试器,点击“暂停”按钮并查看堆栈跟踪即可。

然而,现在,如果问题出在异步方法中,则这种方法不起作用 - 因为要执行的下一段代码被埋在延续任务中的某个地方(从技术上讲,它甚至不会挂起)...有没有办法这样通过任务轻松调试?

UPD.

Example:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();           
    }

    private async void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
    {
        await DoHolyWar();
        MessageBox.Show("Holy war complete!");
    }

    public static async Task DoHolyWar()
    {
        await DoHolyWarComplicatedDetails();
        Console.WriteLine("Victory!");
    }

    public static async Task DoHolyWarComplicatedDetails()
    {
        await BurnHeretics();
    }

    public static Task BurnHeretics()
    {
        var tcs = new TaskCompletionSource<object>();

        // we should have done this, but we forgot
        // tcs.SetResult(null);

        return tcs.Task;
    }
}

请注意,如果您启动它并点击“暂停”,您只会看到 DoHolyWar 方法挂起,但您不会看到确切的位置。如果您将 'await' 替换为 .Wait(),并执行相同的操作,您将能够检查挂起的堆栈跟踪。这个例子非常简单,但在实际应用中通常很难发现问题。特别是桌面应用程序将在主线程上运行事件循环,因此即使某些事情“挂起”,并且您点击“暂停”,您也不会知道出了什么问题。


In situations like this, what you can do is go to the debug dropdown menu, go to Windows, and choose the "Tasks" window (The default short cut key combo is "Ctrl+D, K").

这可以让您了解哪些任务挂起。

查找异常长的任务Duration值,这表明任务发生了一些事情并且任务没有完成。如果双击该行,它将带您进入挂起的等待。

我不确定为什么await BurnHeretics();没有显示在我的列表中,但我确实知道该窗口的行为会根据您的操作系统版本而有所不同,因为它依赖操作系统功能来跟踪某些类型的任务。但至少这会告诉你await DoHolyWarComplicatedDetails();挂着,这将引导您检查DoHolyWarComplicatedDetails()这将引导您检查BurnHeretics();这将引导您找到导致挂起的错误。

UPDATE: 我刚刚意识到它确实显示了await BurnHeretics();作为导致阻塞的主要原因。如果你看一下Task专栏,<DoHolyWarComplicatedDetails>d__3意思是“在方法中DoHolyWarComplicatedDetails编译器生成的类<DoHolyWarComplicatedDetails>d__3已安排并正在等待信号到达。”<DoHolyWarComplicatedDetails>d__3是状态机await BurnHeretics();,如果您使用像 DotPeek 这样的反编译器并允许显示编译器生成的代码,您就可以看到它。

[CompilerGenerated]
private sealed class <DoHolyWarComplicatedDetails>d__3 : IAsyncStateMachine
{
  public int <>1__state;
  public AsyncTaskMethodBuilder <>t__builder;
  private TaskAwaiter <>u__1;

  public <DoHolyWarComplicatedDetails>d__3()
  {
    base..ctor();
  }

  void IAsyncStateMachine.MoveNext()
  {
    int num1 = this.<>1__state;
    try
    {
      TaskAwaiter awaiter;
      int num2;
      if (num1 != 0)
      {
        awaiter = MainWindow.BurnHeretics().GetAwaiter();
        if (!awaiter.IsCompleted)
        {
          this.<>1__state = num2 = 0;
          this.<>u__1 = awaiter;
          MainWindow.<DoHolyWarComplicatedDetails>d__3 stateMachine = this;
          this.<>t__builder.AwaitUnsafeOnCompleted<TaskAwaiter, MainWindow.<DoHolyWarComplicatedDetails>d__3>(ref awaiter, ref stateMachine);
          return;
        }
      }
      else
      {
        awaiter = this.<>u__1;
        this.<>u__1 = new TaskAwaiter();
        this.<>1__state = num2 = -1;
      }
      awaiter.GetResult();
      awaiter = new TaskAwaiter();
      Console.WriteLine("Heretics burned");
    }
    catch (Exception ex)
    {
      this.<>1__state = -2;
      this.<>t__builder.SetException(ex);
      return;
    }
    this.<>1__state = -2;
    this.<>t__builder.SetResult();
  }

  [DebuggerHidden]
  void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
  {
  }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何通过 async/await 找到哪个方法“挂起”? 的相关文章

随机推荐

  • Visual Studio:立即窗口中的 IntelliSense 在哪里?

    看起来 立即 窗口需要一些像 IntelliSense 一样的活力 有人同意 不同意吗 这会在 VS2008 2010 中出现吗 如果您没有自动出现智能感知 请立即按 Ctrl 空格键 和乔尔一样 智能感知似乎是从封闭的窗口中进来的
  • 如何使用 scipy 和 lfilter 进行实时过滤?

    免责声明 我可能不太擅长 DSP 因此在使该代码正常工作时遇到的问题比我应有的要多 我需要在传入信号发生时对其进行过滤 我试图让这段代码工作 但到目前为止我还无法做到 参考文献scipy signal lfilter 文档 https do
  • 为什么 Msxml DocumentElement/SelectSingleNode 不返回任何内容?

    DocumentElement 属性和 SelectSingleNode 继续不返回任何内容 我已经验证 xml 加载正确 问题似乎出在 xml 解析器中 xml 没有任何命名空间 因此不需要设置 Private Function Pars
  • 使用 IntlDateFormatter 格式化 PHP 日期

    我注意到 当用 PHP 格式化日期时IntlDateFormatter http php net manual en class intldateformatter php根据语言的不同 结果可能会有很大不同 例子 formatter ne
  • 不同窗口大小的滚动总和

    我正在寻找随着窗口大小变化计算滚动总和的最快方法 我使用下面的代码 但是对于长度为 1M 的向量来说 它太慢了 Thanks set seed 1 n 10L x runif n window pmin sample 1 10 n TRUE
  • Twbs分页无法加载数据表中的新页面数据

    您好 我正在处理分页 发现当我单击第二页时无法从 twbs 插件加载数据 事实上 该方法是从 ajax 调用中调用的 但数据表数据仍然相同 有人可以告诉我该怎么做才能用服务器上的新数据填充表格 查看 thymeleaf 和 spring b
  • 更新的运行状况检查是否会导致 App Engine 部署失败?

    我们将谷歌应用程序引擎运行状况检查从旧版本更新为新版本 现在我们的部署失败了 该项目的其他内容没有改变 我们测试了默认设置 然后进行了扩展检查以防万一 这是错误 ERROR gcloud app deploy Error Response
  • Firebase 存储 getMetadata() 问题

    我一直在尝试从 Firebase Storage 获取图像文件的元数据 md5hash 并检查它是否与用户手机上图像文件的 md5hash 不相等 问题是 即使哈希值相同 我得到的结果也是不同的 这是我试图获取元数据并进行比较的代码 for
  • 测试所有对象是否具有相同的成员值

    我有一个简单的课程python questions tagged python class simple object def init self theType someNum self theType theType self some
  • ListView 滚动 - 一项一项

    我有一个必须一次显示 4 个项目的 ListView 我必须一项一项地滚动 用户滚动 ListView 后 我必须重新调整滚动以适合 4 个项目 我的意思是 我无法将某个项目显示一半 还有一个问题 有没有办法获取当前ListView的scr
  • 如何为 Azure 表存储 REST 请求生成 SharedKeyLite

    我尝试使用 Postman 调用 Azure 表存储 但不断收到 服务器无法验证请求 确保值 授权标头格式正确 包括签名 我在 Postman 中用于预调用脚本的代码如下 var storageAccount mystorageaccoun
  • Python selenium:显式等待加载两个元素之一

    有没有一种方法可以让我等待两个元素之一加载到硒中 我正在使用显式等待 到目前为止 还无法找到解决方案 简单地做 WebDriverWait driver 5 until lambda driver driver find element B
  • jQuery Mobile 背景图像未显示在全屏 iPad Web 应用程序上

    我已经在 data role page 元素上设置了背景 如下所示 div style background transparent url img background jpg no repeat 它在桌面浏览器和 iPad safari
  • 有没有类似Codecademy for Java的东西[关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 有谁知道像这样的网站代码学院 http www codecademy com专注于 Java 编程教学 Codeacademy com 使用 Java
  • 在没有验证的情况下模仿验证行为

    我们的应用程序中有几个数据对象最终绑定到网格 我们让它们实现 IDataErrorInfo 接口 以便通过向属性添加错误消息 我们可以看到行标题更改样式并且 DataGridCell 获得红色边框 一切都很好 我们现在有一个额外的要求 即我
  • PostgreSQL INSERT FROM SELECT 带有附加列

    我有桌子T1在数据库中DB1和桌子T2在数据库中DB2 这些表具有几乎相同的列集 除了列C additional in T1 它不存在于T2 我需要传输所有行T2 to T1 设置某个值C additional对于我插入的每一行 例如 T1
  • 如何使用 Ionic 3 将 Node JS 升级到 v14.x?

    根据我在这个 TS Node 项目中遇到的错误 对于简单的 TypeScript 仅 REST API 建议的修复 此处提到 https github com heineiuo rippledb issues 148 https githu
  • 在 Cakephp 中插入数据时出现问题

    在执行 add 方法后的数据库中 我仅检索外键 tarid id 其他字段为空这是我的粘附模型代码 感谢您的回答
  • 对字符串中的复杂分隔符序列使用随机 Unicode 是否安全?

    问题 从程序稳定性和确保系统实际运行来看 使用像这样的字符有多安全 or 对于字符串中的复杂分隔符序列 我可以可靠地相信我不会在错误读取这些内容的程序中遇到任何问题吗 我正在使用 C 代码的系统中工作 在该系统中我必须在单个字符串中存储一组
  • 如何通过 async/await 找到哪个方法“挂起”?

    在 旧 时代 跟踪哪个方法挂起非常容易 只需转到调试器 点击 暂停 按钮并查看堆栈跟踪即可 然而 现在 如果问题出在异步方法中 则这种方法不起作用 因为要执行的下一段代码被埋在延续任务中的某个地方 从技术上讲 它甚至不会挂起 有没有办法这样