使用async/await时的堆栈跟踪

60
很明显,由于微软的新编程范式,堆栈跟踪受到了影响。现在我们有一个语义堆栈和一些物理堆栈(这是我选择的词)。
我看到的是异常的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

当然堆栈中可能会混合使用await和内联路径片段。

我尝试查看使用.NET 4.5和async targetting pack的SL5中的堆栈,但还没有尝试WinRT。输出来自.NET 4.5。

在我的主要工作环境SL5中,情况更加棘手:在Silverlight中不会获得堆栈跟踪中的行号(即使具有提升的权限),这使得上下文的需要更为重要。


5
我不知道是否有类似这样的设施。.NET 4.5支持足够详细的ETW跟踪,以便您可以构建一个事件监听器来构建类似于此的堆栈跟踪。但是那需要很多工作,而且我认为SL5也不支持它。 - Stephen Cleary
1
不会的。但是感谢您的评论,负面的信息也是信息。 - John
13
请看这里:http://msdn.microsoft.com/en-us/magazine/jj891052.aspx。 - Toni Petrina
1
不是直接的解决方案,但这里有一个技巧,可以得到异步方法的原始方法。 - Jacek Gorgoń
约翰,你最终做了什么?我自己是SL5用户。 - katit
显示剩余6条评论
1个回答

7

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接