With C# 7 you can now use discards:
_ = WorkAsync();
You can create an extension method that will prevent the warning. The extension method can be empty or you can add exception handling with .ContinueWith()
there.
static class TaskExtensions
{
public static void Forget(this Task task)
{
task.ContinueWith(
t => { WriteLog(t.Exception); },
TaskContinuationOptions.OnlyOnFaulted);
}
}
public async Task StartWorkAsync()
{
this.WorkAsync().Forget();
}
However ASP.NET counts the number of running tasks, so it will not work with the simple Forget()
extension as listed above and instead may fail with the exception:
An asynchronous module or handler completed while an asynchronous operation was still pending.
With .NET 4.5.2 it can be solved by using HostingEnvironment.QueueBackgroundWorkItem
:
public static Task HandleFault(this Task task, CancellationToken cancelToken)
{
return task.ContinueWith(
t => { WriteLog(t.Exception); },
cancelToken,
TaskContinuationOptions.OnlyOnFaulted,
TaskScheduler.Default);
}
public async Task StartWorkAsync()
{
System.Web.Hosting.HostingEnvironment.QueueBackgroundWorkItem(
cancelToken => this.WorkAsync().HandleFault(cancelToken));
}
My two way of dealing with this.
Save it to a discard variable (C# 7)
Example
_ = Task.Run(() => DoMyStuff()).ConfigureAwait(false);
Since the introduction of discards in C# 7, I now consider this to be better than supressing the warning. Because it not only supresses the warning, but also makes the fire-and-forget intention clear.
Moreover, the compiler will be able to optimize it away in release mode.
Just suppress it
#pragma warning disable 4014
...
#pragma warning restore 4014
is a nice enough solution to "fire and forget".
The reason why this warning exists is because in many cases it is not your intention to use an method that returns task without awaiting it. Suppressing the warning when you do intend to fire and forget makes sense.
If you have trouble remembering how to spell #pragma warning disable 4014
, simply let Visual Studio add it for you. Press Ctrl+. to open "Quick Actions" and then "Suppress CS2014"
All in all
It's stupid to create a method that takes a few more ticks to execute, just for the purpose of suppressing a warning.
You can decorate the method with the following attribute:
[System.Diagnostics.CodeAnalysis.SuppressMessage("Await.Warning", "CS4014:Await.Warning")]
static async Task StartWorkAsync()
{
WorkAsync();
// ...
}
Basically you are telling the compiler that you know what you are doing and it does not need to worry about possible mistake.
The important part of this code is the second parameter. The "CS4014:" part is what suppresses the warning. You can write anything you want on the rest.
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