2016-04-25 2 views
4

При использовании задач вы должны проявлять особую осторожность при обработке исключений, вот пример:Задача с встроенной обработкой исключений?

class Program 
{ 
    static void Main(string[] args) 
    { 
     Task<int> task = new Task<int>(Test); 
     task.ContinueWith(ExceptionHandler, TaskContinuationOptions.OnlyOnFaulted); 
     task.Start(); 
     Console.ReadLine(); 
    } 

    static int Test() 
    { 
     throw new Exception(); 
    } 

    static void ExceptionHandler(Task<int> task) 
    { 
     var exception = task.Exception; 
     Console.WriteLine(exception); 
    } 
} 

От here

Мой вопрос, есть ли способ сделать собственную задачу, которая будет обрабатывать (log to service) все исключения без указания его разработчиком вручную. Какое-то наследие помощи.

+0

Вы можете получить из ['Задача'] (https://msdn.microsoft.com/en-us/library/system.threading.tasks.task (v = vs.110) .aspx). Возможно, создайте собственный класс задач, который вызывает 'base.ContinueWith (ExceptionHandler, TaskContinuationOptions.OnlyOnFaulted);' перед вызовом 'base.Start()' в куске созданного вами метода 'Start()'. – Quantic

+0

Я не уверен, понимаю ли я весь прецедент. Но то, что вы могли бы попробовать, - это исключение и исключение журнала на самом высоком уровне. Если выбрано исключение, это, скорее всего, означает, что ваше приложение в любом случае находится в некорректном состоянии. – Karolis

ответ

0

Вы можете создать MyLoggingTask в качестве подкласса Задачи, внедряя соответствующие вам конструкторы, или все они должны быть в безопасности (я вижу 8 из них в .NET Framework 4.5) и переопределяют Start().

Затем либо замените каждое использование задачи MyLoggingTask + ссылкой на пространство имен вашего подкласса, либо минимизируйте «ручной» аспект с помощью using Task = Your.NameSpace.MyLoggingTask, создав псевдоним задачи, который на самом деле является вашим собственным классом.

В качестве альтернативы вы можете создать метод расширения public static StartWithLogging<T>(this Task<T> task), который позаботится о ContinueWith. Затем замените каждый вызов Start() на StartWithLogging() + ссылку на пространство имен вашего класса расширения.

Боюсь, что нет более простых вариантов, и определенная степень «ручного указания» всегда будет необходима.

Смежные вопросы