简体   繁体   中英

Centralizing exceptions from asynchronous tasks

I implemented a custom HandleErrorAttribute in my MVC application and it's been working great to somehow centralize and catch ALL the exceptions that occur in the application.

public class CustomHandleErrorAttribute : HandleErrorAttribute
{
    public override void OnException(ExceptionContext filterContext)
    {
        ....
    }
}

Problem is: I've started to implement some async tasks, like this one:

Task.Factory.StartNew(() => DoSomethingAsync());

And realized that my CustomHandleErrorAttribute is not intercepting the exceptions that happen in those methods: in this case, if an exception takes place inside the DomeSomethingAsync() method, then my HandleErrorAttribute won't catch it; and Global.asax wont either.

What's a good implementation for centralizing exceptions that occur in asynchronous tasks? I don't want to implement a simple try/catch block in every method: I want to count with some kind of handler that captures them.

A good way is to not use Task.Factory.StartNew , especially not on async methods.

Simply invoke the async method directly and await the returned task. Exceptions in that task will be rethrown and handled by the same mechanism as all your other exceptions:

await DoSomethingAsync();

Task.Factory.StartNew is useful for offloading work to aa ThreadPool thread, however you're already on a ThreadPool thread so this isn't needed.

If you want to abandon that task, you should realize nothing guarantees it would continue running. The application pool can be recycled while the task is running because nothing waits for it.

If you want to do "fire and forget" in asp.net you should use something like HangFire (more in Fire and Forget on ASP.NET )


In the world outside asp.net you can simply add a handler as a continuation using ContinueWith with TaskContinuationOptions.OnlyOnFaulted to make sure it only runs if there were exceptions, for example with an extension method:

public static void HandleExceptions(this Task task)
{
    task.ContinueWith(
        faultedTask => HandleException(faultedTask.Exception),
        TaskContinuationOptions.OnlyOnFaulted);
}

And use it like this:

DoSomethingAsync().HandleExceptions();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM