Unmangling (pre.NET 4.5) async/await стеки трассировки

Так как предварительные версии .NET 4.5 (в том числе SL/WP) не поддерживают асинхронный поиск, трассировки стека они генерируют генерируемые имена компилятора класса/метода (например, d_15).

Кто-нибудь знает утилиту, которая генерирует лучшую трассировку стека, с учетом времени выполнения stacktrace, сборки и pdb?

Чтобы быть ясным: Я не ищу полный стек async, просто лучшее представление о том, какой метод действительно исключил исключение

Кажется, что вышеприведенное утверждение недостаточно ясно, вот пример:

public async void Foo()
{
    await Bar();
}

public async Task Bar()
{
    async SomethingToMakeThisMethodAsync();

    throw new Exception()
}

Когда выбрано исключение, Bar, stacktrace будет содержать только сгенерированные имена методов (d_15()). Мне все равно, что Foo назвал Bar. Я просто хочу знать, что Bar был методом, который выбрал исключение

Ответ 1

У Андрея Стасюка есть отличная статья в журнале MSDN http://msdn.microsoft.com/en-us/magazine/jj891052.aspx, в котором подробно описаны последовательности асинхронных причинно-следственных связей как способ помочь в отладке в свете непересекающиеся и запутывающие трассировки стека.

Ответ 2

Похоже, вы потратили впустую свою репутацию на награду, так как этот вопрос задавали несколько раз раньше, например, в:

который, как я помню, имел немного щедрот, но не получил гораздо больше, чем ref:

Или в этом вопросе SO:

со ссылкой в ​​ответ на:

Другой подобный вопрос SO:

Я нашел сборник ссылок на Parallel Debugging (Parallel Stacks, Parallel Tasks) в Visual Studio 2010 от Daniel Moth, чтобы быть очень полезным

Обновление:

Запустив код

using System;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
  class Program
  {
    static void Main(string[] args)
    {
        Foo();
    }
    public static async void Foo()
    {
      await Bar();
    }

    public static async Task Bar()
    {
      try
      {
        //async SomethingToMakeThisMethodAsync();
        //to make this async
        await TaskEx.Delay(2000);//await Task.Delay(2000);//in .NET 4.5
        throw new Exception();
      }
      catch (Exception)
      {
        throw new Exception("This is Excptn in Bar() method");
      }
    }
  }
}

в VS2010 + режиме отладки Async CTP (F5), я ясно вижу мое сообщение об исключении исключения "Это метод Excptn in Bar()":

enter image description here

enter image description here

В любом случае он идентифицируется как ConsoleApplication1.Program. Bar в трассировке стека (окно локалей) даже без какой-либо дополнительной маркировки (исключение перехвата с использованием настраиваемого сообщения), т.е. выше кода метод Bar():

public static async Task Bar()
{
    //async SomethingToMakeThisMethodAsync();
    //to make this async
     await TaskEx.Delay(2000);//await Task.Delay(2000);//in .NET 4.5
     throw new Exception();
}

Я вижу в трассировке стека, что исключение было выбрано в ConsoleApplication1.Program.<Bar>:

+ $exception    
{System.Exception: Exception of type 'System.Exception' was thrown.

Server stack trace: 
   at ConsoleApplication1.Program.<Bar>d__3.MoveNext() in R:\###Debugging\#seUnmangling (pre .NET 4.5) asyncawait stack traces\AsyncConsole_Sln\1Cons_Prj\Program.cs:line 29

Exception rethrown at [0]: 
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at ConsoleApplication1.Program.<Foo>d__0.MoveNext() in R:\###Debugging\#seUnmangling (pre .NET 4.5) asyncawait stack traces\AsyncConsole_Sln\1Cons_Prj\Program.cs:line 19

Exception rethrown at [1]: 
   at System.Runtime.CompilerServices.AsyncVoidMethodBuilder.<SetException>b__1(Object state)
   at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
   at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()
   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()}   System.Exception

enter image description here