web-dev-qa-db-fra.com

Les exceptions d'une tâche n'ont pas été observées en attendant la tâche ou en accédant à sa propriété d'exception. Par conséquent, l'exception non observée a été

Qu'est-ce que cela signifie et comment le résoudre?

J'utilise des tâches TPL.

Toute l'erreur

Les exceptions d'une tâche n'ont pas été observées en attendant la tâche ou en accédant à sa propriété d'exception. Par conséquent, l'exception non observée a été renvoyée par le thread du finaliseur.

à System.Threading.Tasks.TaskExceptionHolder.Finalize ()

mscorlib

93
MonsterMMORPG

Si vous créez une tâche et que vous n'appelez jamais task.Wait() ou n'essayez pas de récupérer le résultat d'un Task<T>, lorsque la tâche est collectée par le ramasse-miettes, elle détruira votre application lors de la finalisation. Pour plus de détails, consultez la page MSDN sur Gestion des exceptions dans le TPL .

La meilleure option ici est de "gérer" l'exception. Cela peut être fait via une continuation - vous pouvez attacher une continuation à la tâche et enregistrer/avaler/etc l'exception qui se produit. Cela fournit un moyen propre de consigner les exceptions de tâches et peut être écrit comme une méthode d'extension simple, c'est-à-dire:

public static void LogExceptions(this Task task)
{
    task.ContinueWith( t =>
    {
         var aggException = t.Exception.Flatten();
         foreach(var exception in aggException.InnerExceptions)
             LogException(exception);
    }, 
    TaskContinuationOptions.OnlyOnFaulted);
}

Avec ce qui précède, vous pouvez empêcher toute tâche de détruire l'application et de la journaliser via:

Task.Factory.StartNew( () => 
   { 
       // Do your work...
   }).LogExceptions();

Alternativement, vous pouvez vous abonner à TaskScheduler.UnobservedTaskException et le gérer là-bas.

151
Reed Copsey

Sûr; cela signifie qu'un Task a été finalisé après avoir été laissé à la récupération de place, mais la tâche elle-même a échoué. Il existe deux correctifs:

  • gérer les tâches échouent directement (utilisez ContinueWith(...) pour vous abonner, et vérifiez .IsFaulted et .Exception sur le Task dans le paramètre)
  • gérer l'événement TaskScheduler.UnobservedTaskException et le marquer comme observé (appelez e.SetObserved() après avoir enregistré l'erreur)
40
Marc Gravell