Terminate or exit C# Async method with “return”
-
21-12-2019 - |
Question
I was new to the async-await
method in C# 5.0
, and I have few questions in my mind
What is the best way to escape an
async
method if it failed an input argument or null check?What is the logical flow of using
return;
in an Taskasync
method (In some circumstances, it became an infinite loop)?Is
CancellationToken
orTask.Yield
fit better in this scenario?
public Func<AzureBlobInfo, string, Task> UploadSuccessCallBackAsync { get; set; }
private async Task OnUploadSuccessAsync(AzureBlobInfo info)
{
if (this.UploadSuccessCallBackAsync == null)
{
return;
}
var transactionType = this.FormData.Get("transactionType");
if (string.IsNullOrEmpty(transactionType))
{
transactionType = "unknown";
}
await this.UploadSuccessCallBackAsync(info, transactionType);
}
Solution
The best way to "fail upon some problem" IMHO would be to throw the appropriate exception, but you can definitely just use return;
if you prefer to avoid exceptions.
This will create a completed/faulted task that was completed synchronously, so the caller using await
will get a finished task and continue on using the same thread.
CancellationToken
allows for the caller to cancel the operation, which isn't the case you are describing.Task.Yield
doesn't terminate any operation, it just enables other tasks to run for some time and reschedules itself for later.
OTHER TIPS
You can safely return from an async method at any moment. In your case (method returning a Task) the compiler will generate a terminated task, so any caller awaiting on your function will continue.
When throwing an exception from an async
method it gets captured in the task so it does not get thrown until the task is observed by calling Task.Wait()
, Task.Result
, awaiting the task or accessing the Exceptions
property of the task.
In terms of input arguments one way to get around that is to split the method into two parts, the first checks the input arguments and then calls the second method which is async
. See this questions answer by Stephen Cleary for an example. That way the input argument exception will be thrown straight away outside of the task returned by the method.