C# 当所有对象与新对象进行多次等待时

C# 当所有对象与新对象进行多次等待时,c#,async-await,C#,Async Await,两者之间有区别吗 var taskA = GetObjectA(); var taskB = GetObjectB(); var taskC = GetObject3(); await Task.WhenAll(taskA, taskB, taskC); return new AllTasksResponse { A = taskA.Result, B = taskB.Result, C = ta

两者之间有区别吗

    var taskA = GetObjectA();
    var taskB = GetObjectB();
    var taskC = GetObject3();

    await Task.WhenAll(taskA, taskB, taskC);

    return new AllTasksResponse
    {
        A = taskA.Result,
        B = taskB.Result,
        C = taskC.Result
    };

?


基本上,我想知道创建一个等待多个任务完成的新对象是否会异步运行它们。或者我应该在这些情况下使用WhenAll(或WaitAll)来确保所有任务并行运行吗?

是的,两者之间存在巨大差异

  • 在第一种情况下,假设三个任务之间没有资源争用,那么这三个任务将并行并独立地进行

    然而,在第二种情况下,他们只会一个接一个地进行

  • 对于
    WhenAll()
    的影响也很重要

  • 根据实际的同步上下文(如果有的话),两种情况下出现潜在死锁的点也不同

  • 任务引发的异常可见的点不同


  • 有一个显著的区别:第一个是并行运行的,第二个是顺序运行的。您应该使用哪一个取决于具体场景是的,启动三个任务然后将它们传递给
    WhenAll()
    ,与单独启动和等待每个任务(一次一个)相比有很大的不同。请参阅副本。(注意:即使使用
    WhenAll()
    ,也最好使用
    wait
    来检索结果,而不是
    result
    属性。)重复的问题是,当您依次等待多个任务时,差异非常明显。但在本例中,我想知道使用“newobject()”(甚至返回)是否会改变这种情况。我不确定它们是否仍然按顺序运行,而不是并行运行。“当您按顺序等待多个任务时,差异非常明显”——这正是您在这里所做的。我不知道你为什么认为这与副本中的同一个问题完全不同。“新对象”只是一种转移注意力的手段。它与async/await无关。这只是创建对象,然后按顺序分配三个属性的语法糖。序列在大括号内而不是作为单独的程序语句是无关紧要的。@Theodor:我不同意。虽然问题的呈现方式不同,但原始副本的答案直接解决了该场景。尽管如此,我还是更新了副本,以包含一个您应该更直接地找到的副本。我将重点放在调用线程在等待过程中被释放的声明上,以便执行其他工作。这种说法是正确的,但这两种方法(并发和顺序)都是正确的。那么,为什么会有差异呢?我的建议是把它从名单上删除。现在我明白你的意思了,谢谢。让我看看我是否可以用更好的方式重新表述。例外情况在这两种情况下都没有什么不同
    await
    从聚合异常中获取第一个内部异常,因此即使在这种情况下,也会观察到相同的异常。@TanveerBadar否,它不会。您可以运行以下代码,并看到只有一个内部异常,而不是两个,即使
    时所有的
    都有两个任务都出现故障。如果您使Foo不
    async
    ,并且只返回所有
    返回的内容,那么您将得到两个异常。不过,您不需要使用
    wait
    来保存它们<代码>异步任务Foo()=>等待Task.WhenAll(Task.FromException(新异常(“第一”)),Task.FromException(新异常(“第二”));var task=Foo();WriteLine(task.Exception.InnerExceptions.Count)
    @TanveerBadar在该示例中,他们不是在检查捕获的异常,而是在等待之前检查由
    返回的任务。因此,他们再次颠覆了
    wait
    的异常行为,正是因为这不是他们想要的。在这个玩具示例中,它是可管理的,因为异常是在包含
    whalll
    的方法中捕获的,但是如果您将异常进一步抛出堆栈,那么获得该任务将更加困难。当然,在问题的例子中,任务从未存储在任何变量中,它只是等待。
    return new AllTasksResponse
    {
        A = await GetObjectA(),
        B = await GetObjectB(),
        C = await GetObjectC()
    };