Visual Studio emits a warning for this code ('because this call is not awaited, execution of the current method continues before the call is completed').
static void Main(string[] args)
{
FireAndForget(); // <-- Warning CS4014
// Do something else.
}
static async Task FireAndForget()
{
// Do something (cannot throw).
}
My understanding is that it is OK not to wait for the task in this particular case because FireAndForget will never throw an exception.
Instead of disabling the warning with a pragma, I was considering changing the return type of FireAndForget from Task to void. That effectively silences the compiler.
static async void FireAndForget() // <-- Task changed to void
{
// Do something (cannot throw).
}
However, according to Stephen Cleary, 'async void' methods should be avoided so I am not quite sure what to do.
Is it OK to have a 'async void' method if the method is not designed to be awaitable in the first place and if no exception will be thrown?
You use the void return type in asynchronous event handlers, which require a void return type. For methods other than event handlers that don't return a value, you should return a Task instead, because an async method that returns void can't be awaited.
In short, if your async method is an event handler or a callback, it's ok to return void .
Async functions always return a promise. If the return value of an async function is not explicitly a promise, it will be implicitly wrapped in a promise.
The call to the async method starts an asynchronous task. However, because no Await operator is applied, the program continues without waiting for the task to complete. In most cases, that behavior isn't expected.
It's extremely rare to have a true fire-and-forget operation; that is, an operation where:
Particularly with the last of these; most so-called "fire-and-forget" operations are not actually fire-and-forget because some action needs to be taken if it doesn't succeed.
That said, there are a few situations where a true fire-and-forget is applicable.
I prefer to use async Task
and avoid the compiler warning by assigning the task to an otherwise unused variable:
var _ = FireAndForget();
async Task
methods are more reusable and testable than async void
methods.
However, I wouldn't throw a fit if a developer on my team just used async void
instead.
Is it OK to have a 'async void' method if the method is not designed to be awaitable in the first place and if no exception will be thrown?
Although it may be "OK" to do so, I would still encourage you to make the method async Task
. Even though you are a 100 percent sure this method won't throw, and isn't ment to be awaited, you never know how it might end up getting used. You're now fully aware of what the consequences of using async void
are, but if there's a slight chance that someone might need to use this in the future, then you're better of putting a nice comment on why this Task
isn't being awaited instead of going with the easy path of making this void
.
Don't let the compiler warnings worry you, I would say worry about the correctness and the effects this may have on your codebase.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With