繁体   English   中英

如何确保任务已启动并安全启动?

[英]How to make sure a task is started and safely start it if not?

我从我无法控制的地方得到IEnumerable<Task> tasks 我不知道这些任务是否是使用new TaskTask.Run手动创建的,或者它们是否是异步方法调用async Task DoSomethingAsync()

如果我确实await Task.WhenAll(tasks) ,则可能会无限期挂起,因为可能没有启动一个或多个任务。

我不能执行tasks.ForEach(t => t.Start()) ,因为如果来自异步方法调用(已经启动),我将收到InvalidOperationException“ tasks.ForEach(t => t.Start())风格的任务可能不会调用Start” 。

我不能await Task.WhenAll(tasks.Select(t => Task.Run(async () => await t)))因为每个t仍然不只是通过等待而开始。

我认为该解决方案与基于此检查每个任务的StatusStart()有关,但我也认为它可能很棘手,因为该状态随时可能更改,对吗? 如果这仍然是路要走,应该检查哪些状态正确,我应该担心哪些线程问题?

非工作案例示例:

//making an IEnumerable as an example, remember I don't control this part
Task t = new Task( () => Console.WriteLine("started"));
IEnumerable<Task> tasks = new[] {t};

//here I receive the tasks
await Task.WhenAll(tasks);//waits forever because t is not started

工作案例示例:

//calls the async function, starting it.
Task t = DoSomethingAsync();
IEnumerable<Task> tasks = new[] {t};

//here I receive the tasks and it will complete because the task is already started
await Task.WhenAll(tasks);

async Task DoSomethingAsync() => Console.WriteLine("started");

如果由于某种原因您无法将代码更改为不返回未启动的任务,则可以检查“ Status并启动任务,如果它具有“已Created状态:

if (task.Status == TaskStatus.Created)
   task.Start();

所有其他任务状态均指示任务已完成,正在运行或正在计划中,因此您无需在该状态下启动任务。

当然,从理论上讲,这会引入竞争条件,因为可以在检查和Start呼叫之间直接开始任务,但是正如Servy在注释中正确指出的(如果此处存在竞争条件),这意味着另一方(创建了该任务) 正在尝试启动它。 即使您处理异常( InvalidOperationException )-另一方也不太可能这样做,因此在尝试启动自己的任务时也会获得异常。 因此,只有一方(您或创建该任务的代码)应尝试启动它。

就是说-比这样做要好得多,因为要确保您永远不会遇到未启动的任务,因为将这样的任务返回到外部代码是很糟糕的设计,至少没有明确指出(虽然在某些用例中可以在内部使用未启动的任务)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM