60 votes

Empiler les traces avec async / wait

Il est clair pourquoi les traces de pile sont touchés avec Microsoft nouveau paradigme de programmation. Nous avons maintenant une sémantique de la pile et un couple de physique (mon choix de mots).

Ce que je vois est une exception de l' StackTrace de la propriété (et dans le débogueur) est la physique, concaténés:

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: Est-il (pratique, standard) moyen de convertir ce pour une bonne trace dans le sens sémantique, tels que:

CheckFooAndBar
Foo
Bar

Bien sûr, il pourrait être un mélange de attend et dans la ligne de chemin de fragments dans la pile.

J'ai essayé de regarder la pile comme il est avec .NET 4.5 et SL5 avec async cibler pack, mais pas encore avec WinRT. La sortie est de .NET 4.5.

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

7voto

John Points 1079

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, voir cet article de blog .

5voto

Foxfire Points 4503

Juste pour être complet:

Andrew Stasyuk. Suivi de chaîne de causalité async

a une solution à votre problème.

-1voto

Les valeurs stockées dans TLS persistent.

Ils persistent après une discussion est renvoyée à la pool de threads et quand il est ensuite réutilisé.

À un certain point, la valeur doit être retiré de TLS (sinon, une autre opération asynchrone d'exécution sur ce fil plus tard peut accéder à la valeur stockée par l'opération précédente, comme si il s'agissait de ses propres).

Il est impossible de impliment présent dans TaskWaitBegin gestionnaire d'événement, parce que dans tous les cas où imbriquée attend sont utilisés, TaskWaitBegin et TaskWaitEnd les événements vont se produire à de nombreuses reprises, précisément, une fois par attendre alors à une valeur stockée peut être nécessaire entre les deux.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X