Fire-and-forget with async vs "old async delegate"
As noted in the other answers, and by this excellent blog post you want to avoid using async void
outside of UI event handlers. If you want a safe "fire and forget" async
method, consider using this pattern (credit to @ReedCopsey; this method is one he gave to me in a chat conversation):
Create an extension method for
Task
. It runs the passedTask
and catches/logs any exceptions:static async void FireAndForget(this Task task) { try { await task; } catch (Exception e) { // log errors } }
Always use
Task
styleasync
methods when creating them, neverasync void
.Invoke those methods this way:
MyTaskAsyncMethod().FireAndForget();
You don't need to await
it (nor will it generate the await
warning). It will also handle any errors correctly, and as this is the only place you ever put async void
, you don't have to remember to put try/catch
blocks everywhere.
This also gives you the option of not using the async
method as a "fire and forget" method if you actually want to await
it normally.
Avoid async void
. It has tricky semantics around error handling; I know some people call it "fire and forget" but I usually use the phrase "fire and crash".
The question is: Given a synchronous method A(), how can I call it asynchronously using async/await in a fire-and-forget manner without getting a solution that is more complicated than the "old way"
You don't need async
/ await
. Just call it like this:
Task.Run(A);
To me it seems that "awaiting" something and "fire and forget" are two orthogonal concepts. You either start a method asynchronously and don't care for the result, or you want to resume executing on the original context after the operation has finished (and possibly use a return value), which is exactly what await does. If you just want to execute a method on a ThreadPool thread (so that your UI doesn't get blocked), go for
Task.Factory.StartNew(() => DoIt2("Test2"))
and you'll be fine.