web-dev-qa-db-fra.com

Empiler les traces avec async / wait

Il est clair pourquoi les traces de pile sont affectées par le nouveau paradigme de programmation de Microsoft. Nous avons maintenant une pile sémantique et quelques physiques (mon choix de mots).

Ce que j'obtiens est la propriété StackTrace d'une exception (et dans le débogueur) est la propriété physique, concaténée:

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

Cela donne:

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 

Ma question est la suivante: existe-t-il un moyen (pratique, standard) de convertir cela en une trace appropriée au sens sémantique, comme:

CheckFooAndBar
Foo
Bar

Bien sûr, il peut y avoir un mélange d'attente et de fragments de chemin en ligne dans la pile.

J'ai essayé de regarder la pile telle qu'elle est avec .NET 4.5 et SL5 avec le pack de ciblage asynchrone, mais pas encore avec WinRT. La sortie provient de .NET 4.5.

Dans SL5, ce que je fais principalement, la situation est plus problématique: vous n'obtenez pas de numéros de ligne dans les traces de pile dans Silverlight (même avec des privilèges élevés), ce qui rend le besoin de contexte plus important.

57
John

Avec Visual Studio 2013 et .NET 4.5.1, ce problème semble être résolu - et pas seulement dans .NET.

Pour plus d'informations, consultez cet article de blog .

6
John