C# 如果我等待已经运行或正在运行的任务,会发生什么情况?

C# 如果我等待已经运行或正在运行的任务,会发生什么情况?,c#,.net,asynchronous,parallel-processing,task-parallel-library,C#,.net,Asynchronous,Parallel Processing,Task Parallel Library,有一个任务变量,假设任务正在运行。。通过执行以下行 await _task; 我想知道当我写这段代码时会发生什么: await _task; await _task; 它会执行两次任务吗?或者抛出异常,因为它已运行 它会执行两次任务吗?或者抛出异常,因为它已 已经跑了 否和否。await唯一做的事情就是调用Task.GetAwaiter,它不会导致任何东西运行。如果任务已经运行到完成,它将提取值(如果它是任务),或者同步运行到下一行(如果它是任务),因为对已经完成的任务进行了优化 一个简单的

有一个任务变量,假设任务正在运行。。通过执行以下行

await _task;
我想知道当我写这段代码时会发生什么:

await _task;
await _task;
它会执行两次任务吗?或者抛出异常,因为它已运行

它会执行两次任务吗?或者抛出异常,因为它已 已经跑了

否和否。
await
唯一做的事情就是调用
Task.GetAwaiter
,它不会导致任何东西运行。如果任务已经运行到完成,它将提取值(如果它是
任务
),或者同步运行到下一行(如果它是
任务
),因为对已经完成的任务进行了优化

一个简单的演示:

async Task Main()
{
    var foo = FooAsync();
    await foo;
    await foo;

    var bar = BarAsync();
    var firstResult = await bar;
    var secondResult = await bar;

    Console.WriteLine(firstResult);
    Console.WriteLine(secondResult);
}

public async Task FooAsync()
{
    await Task.Delay(1);
}

public async Task<int> BarAsync()
{
    await Task.Delay(1);
    return 1;
}

设置基础
任务的结果,这样您就可以同步获得值。

我创建了这个快速测试:

var i = 0;
var task = Task.Run(() => { i++; Console.WriteLine(i); return i; });

var x = await task;
var y = await task;

Console.WriteLine(x);
Console.WriteLine(y);
它写道:

1
1
1

因此,很明显,任务只运行一次。

应该注意,这是一件好事。异步代码的一个棘手部分是,大多数异步操作实际上可以同步完成——这是您必须处理的另一种情况,因为在这种情况下不会调用异步回调
Wait
对您隐藏了所有这些复杂性,它允许您在十个不同的位置
Wait
相同的任务(对于异步延迟初始化非常有用)。我可以保证任务所指向的方法不会执行两次,即使任务正在运行或已经运行?@BilalFazlani是的,您可以。如果
任务
已经完成,它将简单地打开结果。@BilalFazlani-您是否知道有一个特定的类专门用于帮助延迟初始化?-你为什么不试试呢?测试并不难。这里需要了解的关键是Wait不会运行任务。异步等待任务完成。因此得名“等待”。有一个持续的神话,等待开始一项任务,但它当然不是;在你等待的时候,你已经有了一个开始的任务在手。真正让我大开眼界的是“继续”的概念。我认为没有这种洞察力,很难理解“等待”。谢谢@Enigmativity。那真的很有帮助
var i = 0;
var task = Task.Run(() => { i++; Console.WriteLine(i); return i; });

var x = await task;
var y = await task;

Console.WriteLine(x);
Console.WriteLine(y);
1
1
1