这两者非常相似。遇到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。
一个叫做'First',另一个叫'Second'。一个是“异步”,另一个不是。这不是http://puzzling.stackexchange.com。你真的想知道什么?你的问题[如何异步调用同步方法](http://stackoverflow.com/questions/18830397/awaiting-a-non-async-method)? – CodeCaster
@CodeCaster:这是一个合理的问题。即使两者之间没有功能上的差异(事实并非如此),OP的要求也是合理的。但是,这可能是一个重复的问题。 – Douglas
为了DRY的利益标记为重复。尽管它的标题,链接的问题和它接受的答案主要讨论'Task.Delay'的情况,而不是'Task.Run'。 – Douglas