Если вы хотите регистрировать исключения для задач запуска и забывания, вот хороший метод расширения, который вы можете использовать:
public static Task OnExceptionLogError(this Task task, string message)
{
task.ContinueWith(t =>
{
var exception = t.Exception;
var innerExceptions = exception.Flatten().InnerExceptions;
var lines = innerExceptions.Select(ex => $"{ex.GetType().FullName}: {ex.Message}");
string literal = innerExceptions.Count == 1 ? "an exception" : $"{innerExceptions.Count} exceptions";
WriteToTextFile($"{message}, {literal} occured on task #{task.Id}:\r\n " + String.Join("\r\n ", lines));
}, TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.ExecuteSynchronously);
return task;
}
Пример использования:
Task.Factory.StartNew(
async () =>
{
WriteToTextFile("About to call ExecuteRequest");
response = await ExecuteRequest(clientRequestContent);
WriteToTextFile("Response received:" + response);
}).OnExceptionLogError("ClientRequestContent"); // <--- give a title for the error
В нем регистрируются все возможные вложенные ошибки, которые могли быть сгруппированы, например, путем вызова Task.WhenAll
.
Вот еще один способ регистрации исключений из задач запуска и забывания. Он имеет преимущество в том, что он является глобальным обработчиком в одном месте, и недостатком в том, что он не может регистрировать больше информации об ошибке, кроме самого исключения.
static void Main(string[] args)
{
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
// ...
}
private static void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
// Log the e.Exception, which is an AggregateException
WriteToTextFile("Exception from task:" + e.Exception);
}
Обновление: Предостережения:
1) Событие TaskScheduler.UnobservedTaskException
возникает, когда задача собирается сборщиком мусора, и это может произойти намного позже или не произойти вовсе!
2) Это событие не вызывается в сборках отладки, только в сборках выпуска !