【问题标题】:Stack traces with async/await使用 async/await 进行堆栈跟踪
【发布时间】:2012-12-02 19:03:57
【问题描述】:

很清楚为什么堆栈跟踪会受到微软新的编程范式的影响。我们现在有一个语义堆栈和几个物理堆栈(我选择的单词)。

我看到的是异常的StackTrace 属性(在调试器中)是物理属性,串联:

private async Task CheckFooAndBar()
{
    var log = LogManager.GetLogger("Test");
    log.Info("CheckFooAndBar");
    try
    {
        await Foo();
    }
    catch (Exception ex)
    {
        log.Info("StackTrace of last exception: " + ex.StackTrace);
    }
    Console.ReadKey();
}
private async Task Foo()
{
    await Task.Factory.StartNew(() => Thread.Sleep(1000));
    await Bar();
    await Task.Factory.StartNew(() => Thread.Sleep(1000));
}
private async Task Bar()
{
    await Task.Factory.StartNew(() => Thread.Sleep(1000));
    throw new Exception();
    await Task.Factory.StartNew(() => Thread.Sleep(1000));
}

这给出了:

StackTrace of last exception:    at NLogAsyncExceptionTestCase.Program.<Bar>d__d.MoveNext() in c:\Users\Jens\Documents\Visual Studio 2012\Projects\NLogAsyncExceptionTestCase\NLogAsyncExceptionTestCase.Console\Program.cs:line 53
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at NLogAsyncExceptionTestCase.Program.<Foo>d__8.MoveNext() in c:\Users\Jens\Documents\Visual Studio 2012\Projects\NLogAsyncExceptionTestCase\NLogAsyncExceptionTestCase.Console\Program.cs:line 44
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at NLogAsyncExceptionTestCase.Program.<CheckFooAndBar>d__0.MoveNext() in c:\Users\Jens\Documents\Visual Studio 2012\Projects\NLogAsyncExceptionTestCase\NLogAsyncExceptionTestCase.Console\Program.cs:line 30 

我的问题是:有没有一种(方便、标准的)方法可以将其转换为语义上的适当回溯,例如:

CheckFooAndBar
Foo
Bar

当然,堆栈中可能混合有等待和内联路径片段。

我尝试使用 .NET 4.5 和带有异步目标包的 SL5 查看堆栈,但尚未使用 WinRT。输出来自 .NET 4.5。

在我主要做的 SL5 中,情况更成问题:您不会在 Silverlight 的堆栈跟踪中获得行号(即使具有提升的权限),这使得对上下文的需求变得更加重要。

【问题讨论】:

  • 我不知道有这样的设施。 .NET 4.5 确实支持具有足够详细信息的 ETW 跟踪,您可以构建一个事件侦听器来构建这样的堆栈跟踪。但这将是很多工作,而且我认为 SL5 无论如何都不会支持它。
  • 不,不会。但感谢您的评论,负面信息也是。
  • 我写了一个“手动”解决方案on my blog。但是,您确实必须向要包含的每个方法添加代码。 :(
  • 不是直接的解决方案,而是here's a hack 在给定异步方法的情况下获取原始方法。

标签: c# logging stack-trace async-await visual-studio-debugging


【解决方案1】:

使用 Visual Studio 2013 和 .NET 4.5.1,这个问题似乎得到了解决 - 而不仅仅是在 .NET 中。

延伸阅读Debugging Asynchronous Code in Visual Studio 2013 - Call Stack enhancements.

【讨论】:

    猜你喜欢
    • 2013-04-29
    • 1970-01-01
    • 1970-01-01
    • 2019-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-08
    相关资源
    最近更新 更多