在异步/等待调试异常(调用堆栈) [英] Debugging exceptions in a Async/Await (Call Stack)

查看:136
本文介绍了在异步/等待调试异常(调用堆栈)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用的是异步/等待释放我的UI线程和多线程完成。现在我有一个问题,当我打了一个例外。我的异步部分调用堆栈与百达 ThreadPoolWorkQue.Dipatch开始(),这并不能帮助我非常多

I use the Async/Await to free my UI-Thread and accomplish multithreading. Now I have a problem when I hit a exception. The Call Stack of my Async parts allways starts with ThreadPoolWorkQue.Dipatch(), which doesn't help me very much.

我发现了一个MSDN,文章安德鲁Stasyuk。这件事,但是我的理解是,因果异步链追溯它不是一个准备使用的解决方案。

I found a MSDN-Article Andrew Stasyuk. Async Causality Chain Tracking about it but as I understand it, its not a ready to use solution.

什么是如果你使用与异步/多线程等待调试的最佳/最简单的方法是什么?

What is the best/easiest way to debug if you use multithreading with Async/Await?

推荐答案

您发现文中很好地解释为什么调用堆栈不上班的路上我们大多数人认为他们做一个好工作。技术上,调用堆栈只告诉我们哪里的code将返回到当前的方法之后。换句话说,调用堆栈,其中code是怎么回事,而不是里的code是从哪里来的。

The article you found does a good job of explaining why call stacks don't work the way most of us think they do. Technically, the call stack only tells us where the code is returning to after the current method. In other words, the call stack is "where the code is going", not "where the code came from".

有趣的是,这篇文章确实提到在传递一个解决方案,但它并不阐述。我有一个博客贴子,去解释 CallContext中详细解决方案。从本质上讲,你用逻辑调用上下文来创建自己的诊断上下文。

Interestingly, the article does mention a solution in passing, but doesn't expound on it. I have a blog post that goes explains the CallContext solution in detail. Essentially, you use the logical call context to create your own "diagnostic context".

我喜欢的 CallContext中解决方案比文章,因为它的工作在psented解决方案$ P $更好地将所有形式的的异步 code(包括叉/加入code像 Task.WhenAll )。

I like the CallContext solution better than the solution presented in the article because it does work will all forms of async code (including fork/join code like Task.WhenAll).

这是我所知道的最好的解决方案(而不是做一些非常复杂的像挂接到剖析API等)。在 CallContext中办法注意事项:

This is the best solution I know of (other than doing something really complex like hooking into the profiling API). Caveats of the CallContext approach:


  • 它仅适用于.NET 4.5十足。为Windows Store应用程序不支持,.NET 4.0,等等。

  • 您确实有文书你的$ C $手动℃。有没有办法,据我所知,自动注入它。

  • 例外不会自动捕获逻辑调用上下文。所以这个解决方案,如果你打破进入调试器时抛出异常做工精细,但它不是有用,如果你只是赶上在另一个地方的异常并记录它们。

在code(视不可改变的集合的NuGet库):

public static class MyStack
{
    private static readonly string name = Guid.NewGuid().ToString("N");

    private static ImmutableStack<string> CurrentContext
    {
        get
        {
            var ret = CallContext.LogicalGetData(name) as ImmutableStack<string>;
            return ret ?? ImmutableStack.Create<string>();
        }

        set
        {
            CallContext.LogicalSetData(name, value);
        }
    }

    public static IDisposable Push([CallerMemberName] string context = "")
    {
        CurrentContext = CurrentContext.Push(context);
        return new PopWhenDisposed();
    }

    private static void Pop()
    {
        CurrentContext = CurrentContext.Pop();
    }

    private sealed class PopWhenDisposed : IDisposable
    {
        private bool disposed;

        public void Dispose()
        {
            if (disposed)
                return;
            Pop();
            disposed = true;
        }
    }

    // Keep this in your watch window.
    public static string CurrentStack
    {
        get
        {
            return string.Join(" ", CurrentContext.Reverse());
        }
    }
}

用法:

static async Task SomeWorkAsync()
{
    using (MyStack.Push()) // Pushes "SomeWorkAsync"
    {
        ...
    }
}

更新:我发布href=\"http://blog.stephencleary.com/2013/05/announcement-async-diagnostics.html\">的NuGet包(在我的博客中描述的使用PostSharp注入推和自动弹出。因此,获得良好的跟踪应​​该简单得多了。

Update: I released a NuGet package (described on my blog) that uses PostSharp to inject the pushes and pops automatically. So getting a good trace should be a lot simpler now.

这篇关于在异步/等待调试异常(调用堆栈)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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