【问题标题】:What is the difference in behaviour of these two task methods? [duplicate]这两种任务方法的行为有什么区别? [复制]
【发布时间】:2016-03-08 11:01:01
【问题描述】:

方法一:

private static async Task FirstDelayAsync()
{
    await Task.Delay(1000);
}

方法二:

private static Task SecondDelayAsync()
{
    return Task.Delay(1000);
}

请帮我找出区别:

await FirstDelayAsync();
await SecondDelayAsync();

谢谢。

【问题讨论】:

  • 一个叫First,另一个叫Second。一个是async,另一个不是。这不是puzzling.stackexchange.com。你真正想知道什么?你的问题是how to asynchronously call a synchronous method吗?
  • @CodeCaster:这是一个合理的问题。即使两者之间没有功能差异(事实并非如此),OP 也有理由提出要求。然而,这可能是一个重复的问题。
  • 为 DRY 标记为重复。尽管有标题,但链接的问题及其接受的答案主要讨论的是Task.Delay,而不是Task.Run
  • @Douglas 我并不是说这不合法,我是说我不清楚 OP 正在寻找什么样的答案。

标签: c# .net asynchronous


【解决方案1】:

两者非常相似。当遇到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);

在上面的 sn-p 中,ProcessAsync 调用引发的同步异常甚至会阻止后续的异步操作启动,因为该异常会立即停止枚举。对于应该停止整个过程的失败先决条件,这通常是更可取的。

更新:另一个重要的不同是使用await 而不使用ConfigureAwait(false) 将使您的代码更容易死锁。见this answer

【讨论】:

    【解决方案2】:

    在功能上,这两种方法没有区别。它们的工作方式相同。

    asyncawait 允许您编写看起来像同步代码但实际上是异步的代码,从而创建复杂的异步方法。

    对于像您这样的简单情况,首选第二种方法,因为第一种方法会创建一个状态机来处理异步逻辑。在复杂的异步方法的情况下肯定需要这种状态机,但在这种简单的情况下不需要。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-25
      • 1970-01-01
      • 2013-09-08
      • 2019-03-31
      相关资源
      最近更新 更多