堆栈跟踪与异步/的await [英] Stack traces with async/await

查看:131
本文介绍了堆栈跟踪与异步/的await的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这清楚为什么堆栈跟踪与微软的新编程范式的影响。我们现在有一个语义栈和物理夫妇的那些(我选择的话)。

我能看到却是一个例外的堆栈跟踪属性(并在调试器)是物理的人,连在一起:

 专用异步任务CheckFooAndBar()
{
    VAR日志= ​​LogManager.GetLogger(测试);
    log.Info(CheckFooAndBar);
    尝试
    {
        等待美孚();
    }
    赶上(异常前)
    {
        log.Info(最后的异常堆栈跟踪:+ ex.StackTrace);
    }
    Console.ReadKey();
}
私人异步任务美孚()
{
    等待Task.Factory.StartNew(()=> Thread.sleep代码(1000));
    等待吧();
    等待Task.Factory.StartNew(()=> Thread.sleep代码(1000));
}
私人异步任务栏()
{
    等待Task.Factory.StartNew(()=> Thread.sleep代码(1000));
    抛出新的异常();
    等待Task.Factory.StartNew(()=> Thread.sleep代码(1000));
}

这给出了:

 最后一个异常的堆栈跟踪:在NLogAsyncExceptionTestCase.Program<酒吧GT; d__d.MoveNext()在C:\\用户\\延\\文档\\ Visual Studio 2012中\\项目\\ NLogAsyncExceptionTestCase \\ NLogAsyncExceptionTestCase .Console \\的Program.cs:行53
---从previous位置堆栈跟踪,其中引发异常的结尾---
   在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)
   在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)
   在System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   在NLogAsyncExceptionTestCase.Program<富> d__8.MoveNext()在C:\\用户\\延\\文档\\ Visual Studio 2012中\\项目\\ NLogAsyncExceptionTestCase \\ NLogAsyncExceptionTestCase.Console \\的Program.cs:行44
---从previous位置堆栈跟踪,其中引发异常的结尾---
   在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)
   在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)
   在System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   在NLogAsyncExceptionTestCase.Program< CheckFooAndBar> d__0.MoveNext()在C:\\用户\\延\\文档\\ Visual Studio 2012中\\项目\\ NLogAsyncExceptionTestCase \\ NLogAsyncExceptionTestCase.Console \\的Program.cs:行30

我的问题是:是否有一个(方便,标准)的方式来这在语义意义上转换为正确的回溯,如:

  CheckFooAndBar

酒吧

当然有可能在叠层等待着和内嵌路径片段的混合物

我试图寻找在堆栈,因为它与.NET 4.5和SL5与异步目标定位包,但尚未与WinRT的。输出是从.NET 4.5。

在SL5,这是我主要做,情况更成问题:你并没有行号的堆栈跟踪在Silverlight(甚至提升的权限),这使得环境更加重要的需要。

解决方案

与Visual Studio 2013和.NET 4.5.1,这个问题似乎解决 - 不仅在.NET

有关详细信息,请参阅this博客文章

It's clear why stack traces are affected with Microsoft's new programming paradigm. We now have a semantic stack and a couple of physical ones (my choice of words).

What I get to see is an exception's StackTrace property (and in the debugger) is the physical ones, concatenated:

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));
}

This gives:

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 

My question is: Is there a (convenient, standard) way to convert this to a proper backtrace in the semantic sense, such as:

CheckFooAndBar
Foo
Bar

Of course there could be a mixture of awaits and inline path fragments in the stack.

I tried looking at the stack as it is with .NET 4.5 and SL5 with the async targetting pack, but not yet with WinRT. The output is from .NET 4.5.

In SL5, which is what I mainly do, the situation is more problematic: You don't get line numbers in stack traces in Silverlight (even with elevated privileges), which makes the need for context more important.

解决方案

With Visual Studio 2013 and .NET 4.5.1, this problem appears to be addressed - and not only in .NET.

For more information, see this blog post.

这篇关于堆栈跟踪与异步/的await的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆