如果我等待已经运行或运行的任务会怎样? [英] what happens if I await a task that is already running or ran?

查看:112
本文介绍了如果我等待已经运行或运行的任务会怎样?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个Task变量,可以说该任务现在正在运行..通过执行以下行.

There is a Task variable and lets say the task is running right now.. by executing the following line.

await _task;

我想知道编写此代码时会发生什么:

I was wondering what happens when I write this code:

await _task;
await _task;

它将两次执行任务吗?还是因为已经运行而引发异常?

would it execute the task twice ? Or throw an exception because it has already run ?

推荐答案

它将两次执行任务吗?或抛出异常,因为它有 已经运行了吗?

would it execute the task twice ? Or throw an exception because it has already run ?

不,不. await唯一要做的就是调用Task.GetAwaiter,它不会导致任何运行.如果任务已经执行完毕,则如果是Task<T>,则将提取值;如果是Task,则将与下一行同步运行,因为对已经完成的任务进行了优化.

No and no. The only thing await does is call Task.GetAwaiter, it does not cause anything to run. If the task already ran to completion, it will either extract the value if it is a Task<T>, or run synchronously to the next line if it is a Task, since there is an optimization for already completed tasks.

一个简单的演示

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;
}

如果您深入研究状态机本身,则会看到以下内容:

If you drill down to the state machine itself, you'll see this:

this.<foo>5__1 = this.<>4__this.FooAsync();
taskAwaiter = this.<foo>5__1.GetAwaiter();
if (!taskAwaiter.IsCompleted)
{
    this.<>1__state = 0;
    this.<>u__1 = taskAwaiter;
    M.<FooBar>d__0 <FooBar>d__ = this;
    this.<>t__builder.AwaitUnsafeOnCompleted<TaskAwaiter, M.<FooBar>d__0>
                                                    (ref taskAwaiter, ref <FooBar>d__);
    return;
}

此优化首先检查任务的完成.如果任务未完成,它将调用UnsafeOnCompleted,它将注册继续.如果完成,它将破坏switch并转到:

This optimization first checks the completion of the task. If the task isn't complete, it will call UnsafeOnCompleted which will register the continuation. If it is complete, it breaks the switch and goes to:

this.<>1__state = -2;
this.<>t__builder.SetResult();

这将设置基础Task的结果,这样您实际上就可以同步获取该值.

Which sets the result for the underlying Task, and that way you actually get the value synchronously.

这篇关于如果我等待已经运行或运行的任务会怎样?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆