gpt4 book ai didi

c# - 如果 "await"已经被 .Start() 编辑过,它是否会重新生成一个任务?

转载 作者:行者123 更新时间:2023-11-30 20:31:45 27 4
gpt4 key购买 nike

如果我有以下内容:

// a:
// returns a task, then starts and joins it with "await" keyword
var resultA = await GetBigTask();

// b:
// gets a Task<T>, launches it with Start(), then joins it with "await"
var myBigTask = GetBigTask();
myBigTask.Start();
var resultB = await myBigTask;

澄清一下,我的评论是否正确?

在尚未启动的任务上使用“await”关键字(如从 GetBigTask() 返回的匿名任务)将启动它然后加入它。在已经被 .Start() 编辑过的任务上使用“await”关键字将不会启动它的第二个实例,而是加入现有的实例?

因此,如果我有许多完全相互独立的大任务,那么像“c”而不是“d”那样启动它们总是对我有益吗?

// c:
var taskA = GetTaskA();
var taskB = GetTaskB();
var taskC = GetTaskC();

// they are all launched in parallel
taskA.Start(); taskB.Start(); taskC.Start();

// then joined together at the end
await taskA; await taskB; await taskC;

// d:
await GetTaskA();
await GetTaskB(); // not launched until GetTaskA() concludes!
await GetTaskC(); // not launched until GetTaskA() AND B concludes!

这一切都正确吗?如果没有,我如何实现“c”,即一次启动多个(独立的)任务,然后等待它们全部完成?

最佳答案

没有好的Minimal, Complete, and Verifiable code example这清楚地说明了您的问题,因此无法确定您显示的代码会发生什么。也就是说,您的问题中至少存在一些明显的误解:

  • Misconception #1: await starts a task.
  • Misconception #2: await joins a thread.

如果您使用await 来等待尚未启动的任务,它本身不会启动该任务。它将永远等待,除非在其他地方您有一些启动任务的代码。

就“加入”而言,该词通常用于描述当前线程等待某个其他线程或任务的操作。这与 await 所做的完全相反(是的,我意识到术语有点困惑)。当您的执行到达 await 语句时,当前正在执行的方法会在此时返回,从而允许线程继续执行。如果等待的等待完成,执行将在 await 语句之后立即恢复

但在此之前,该线程中的执行不会被阻止(或“加入”)。

await 语句还有其他一些有用的行为:当等待的操作完成时,如果成功完成,await 将检索并返回结果值表达。如果操作不成功而是抛出异常,则异常将被解包并由 await 表达式重新抛出。

在您的示例中,如果 GetBigTask() 从字面上返回一个尚未启动的任务对象,那么简单地使用 await GetBigTask() 将不会执行任何操作很有用,因为等待永远不会完成。如果任务对象已经已经启动,那么调用myBigTask.Start() 将抛出异常。

通常,返回任务对象的异步方法将返回那些处于已运行状态的对象。因此,您的问题可能反射(reflect)了第三种误解:

  • Misconception #3: methods like GetBigTask(), GetTaskA(), etc. return a task object that hasn't yet been started.

诚然,如果没有完整的代码示例,就无法确定。但假设这些方法是由熟悉 C# 中常见异步用法的人编写的,则无需对返回的对象调用 Start()

如果确实如此,那么执行以下操作就足够了:

var taskA = GetTaskA();
var taskB = GetTaskB();
var taskC = GetTaskC();

await taskA;
await taskB;
await taskC;

GetTask...() 方法将以已运行状态返回所有任务。按顺序调用 await 将按顺序处理每个任务的完成,其效果是在所有三个任务完成之前不会继续该方法的其余部分。

关于c# - 如果 "await"已经被 .Start() 编辑过,它是否会重新生成一个任务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42637698/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com