使用async / await堆栈跟踪

时间:2012-12-14 18:37:07

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

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

我看到的是异常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中获得堆栈跟踪中的行号(即使使用提升的权限),这使得对上下文的需求更加重要。

1 个答案:

答案 0 :(得分:6)

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

有关详细信息,请参阅this blog post