I'm struggling with how to perform some very-long-running background processing in a world of async methods.
Using the vocabulary from Stephen Cleary's blog, I'm interested in kicking off a "delegate task" after await
-ing a "promise task". I want to return the promised value as soon as it's available, and let the delegate task continue on in the background.
To handle exceptions in the un-await
-ed delegate task, I'll use an exception-handling continuation modeled after the one described here.
public async Task<int> ComplexProcessAsync()
{
...
int firstResult = await FirstStepAsync();
// THE COMPILER DOESN'T LIKE THIS
Task.Run(() => VeryLongSecondStepIDontNeedToWaitFor(firstResult)).LogExceptions();
return firstResult;
}
Since VeryLongSecondStep...()
could take many minutes, and its results are observable purely by side-effect (e.g. records appearing in a database), I reeeaaalllyy don't want to await
it.
But as pointed out, the compiler doesn't like this. It warns "Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call."
I could ignore the warning, but I get the feeling I'm not doing this in "correct" way. So what is the correct way?
Thanks!
I could ignore the warning, but I get the feeling I'm not doing this in "correct" way. So what is the correct way?
The compiler is warning you that you're not awaiting the task. From my experience, >99% of the time the compiler is correct, the code is wrong because it's missing an await
. So this is one of the rare situations where you know what you're doing and want to live dangerously. :)
In this case, you can explicitly assign the task to an unused variable:
var _ = Task.Run(() => VeryLongSecondStepIDontNeedToWaitFor(firstResult));
The compiler is intelligent enough to understand that you're using this variable to silence the "missing await" warning.
On a side note, I do not recommend ContinueWith
at all; in the async world, it's just a more dangerous version of await
. So I'd write LogExceptions
something like this:
public static async Task LogExceptions(this Task task)
{
try
{
await task.ConfigureAwait(false);
}
catch (Exception ex)
{
LogException(ex);
}
}
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