我是C# 5.0
中async-await
方法的新手,我心中有几个问题
-
什么是最好的方式来逃避
async
方法,如果它失败的输入参数或null检查? -
在任务
async
方法中使用return;
的逻辑流程是什么(在某些情况下,它变成了一个无限循环)? -
CancellationToken
或Task.Yield
在这种情况下更适合?
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);
}
"在某些问题上失败"的最佳方法是抛出适当的异常,但是如果您喜欢避免异常,则绝对可以使用return;
。
这将创建一个同步完成的已完成/故障任务,因此使用await
的调用者将获得一个已完成的任务,并继续使用相同的线程。
-
CancellationToken
允许调用者取消操作,这不是你所描述的情况。 -
Task.Yield
不终止任何操作,它只是允许其他任务运行一段时间,并为以后重新调度自己。
你可以在任何时候安全地从异步方法返回。在你的例子中(方法返回一个Task),编译器将生成一个终止的Task,所以任何等待你的函数的调用者都将继续。
当从async
方法抛出异常时,它被捕获在任务中,因此它不会被抛出,直到通过调用Task.Wait()
, Task.Result
,等待任务或访问任务的Exceptions
属性来观察任务。
在输入参数方面,解决这个问题的一种方法是将方法分成两部分,第一部分检查输入参数,然后调用第二个方法async
。请看Stephen Cleary回答这个问题的例子。这样,输入参数异常将被直接抛出到该方法返回的任务之外。