【问题标题】:How to create infinite running Task loop?如何创建无限运行的任务循环?
【发布时间】:2019-01-24 06:18:41
【问题描述】:

我想创建无限 Task 循环。当任何任务完成工作时,它将从任务列表中删除,并将新任务添加到列表中。我的代码提议:

// create list of 128 task in queue
List<Task> tasks = new List<Task>();
for (int n = 0; n < 128; n++)
{
    tasks.Add(Task.Run(() => JOB(n);
}
// wait for finish and add immediately new running task to the list
while (tasks.Count > 0)
{
    Task firstFinishedTask = Task.WhenAny(tasks);
    tasks.Remove(firstFinishedTask);    // line with problem
    tasks.Add(Task.Run(() => JOB(n);
}

问题是已完成任务未从列表中删除。他们得到了不同的Task.Id,这是巨大的副作用。

【问题讨论】:

  • 当然有办法做到这一点,但是请你解释一下你想要达到的目标,我的蜘蛛侠直觉告诉我有更好的方法
  • 比如什么是job,为什么需要128个,这个IO绑定的work吗?
  • 我会设计它,以便在工作为finished 时发布一个事件。然后删除了those 作业。 - 更容易
  • 无论您的问题是什么,我确信创建一个包含 128 个任务的固定池来解决它是错误的解决方案。
  • @TheGeneral 是的,这是 IO 绑定。从 Internet 下载数据。

标签: c# multithreading task


【解决方案1】:
Task firstFinishedTask = Task.WhenAny(tasks);

这是一个名字错误的变量。 Task.WhenAny 返回 Task&lt;Task&gt;外部 Task 在传递给WhenAny 的任何任务完成时完成。 inner Task 是导致这种情况发生的任务。 WhenAny 本身不执行任何等待。

使用WhenAny通常方式是将它与await 一起使用——它总是会从你传递的内容中删除外部Task,并将内部内容交还给你。

如果您不想将WhenAnyawait 一起使用,您可能正在寻找WaitAny - 这会阻止您当前的线程[:-(] 并返回一个索引而不是@987654334 @,但至少确实等待您通过它完成的任务之一(但正如上面所说的那样,我更愿意看到await Task.WhenAny(tasks)以便释放这个线程)

tasks 不包含WhenAny 创建的外部Task - 这就是您的Remove 尝试失败的原因。

【讨论】:

    猜你喜欢
    • 2014-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多