方法1:
private static async Task FirstDelayAsync()
{
await Task.Delay(1000);
}
方法2:
private static Task SecondDelayAsync()
{
return Task.Delay(1000);
}
请帮我找出差异:
await FirstDelayAsync();
await SecondDelayAsync();
感谢。
答案 0 :(得分:4)
两者非常相似。当遇到async
方法时,C#编译器将生成状态机,以便返回的Task
表示方法的完成。因为你的方法所做的唯一事情是等待另一个异步操作,所以这在功能上几乎等同于直接从内部异步操作返回Task
。
async
方法中执行的任何逻辑,包括方法开头的同步部分(在第一个await
语句之前),将作为异步操作的一部分进行编译。这意味着前提条件异常将不再同步传递,而是通过返回的Task
异步传递:
private static async Task FirstDelayAsync()
{
if (StateNotValid)
throw new NotSupportedException();
await Task.Delay(1000);
}
private static Task SecondDelayAsync()
{
if (StateNotValid)
throw new NotSupportedException();
return Task.Delay(1000);
}
测试上面的代码:
var t1 = FirstDelayAsync();
await t1; // exception thrown here
var t2 = SecondDelayAsync(); // exception thrown here
await t2;
如果您在调用它的同一行上等待异步操作,这将没有什么区别。但是,如果你拖延等待,它会有所作为;例如,如果同时启动多个异步操作,然后使用Task.WhenAll
:
var tasks = Enumerable
.Range(0, 10)
.Select(i => ProcessAsync(i))
.ToArray();
await Task.WhenAll(tasks);
在上面的代码片段中,ProcessAsync
调用引发的同步异常会阻止后续异步操作甚至被启动,因为异常会立即停止枚举。这通常适用于应该停止整个过程的失败前提条件。
更新:另一个重要的不同之处是,使用await
而不使用ConfigureAwait(false)
会使您的代码更容易死锁。请参阅this answer。
答案 1 :(得分:0)
从功能上讲,这两种方法没有区别。他们的工作方式相同。
async
和await
允许您创建复杂的异步方法,允许您编写看起来像同步代码但实际上是异步的代码。
对于像你这样的简单情况,第二种方法是首选方法,因为第一种方法创建了一个状态机来处理异步逻辑。在复杂的异步方法中肯定需要这样的状态机,但对于这种简单的情况不需要。