【问题标题】:Running tasks in sequence inside an infinite loop [closed]在无限循环中按顺序运行任务[关闭]
【发布时间】:2018-03-01 05:24:16
【问题描述】:

我有几个按顺序运行的任务;一个接一个。

Task.Factory.StartNew(() => DoWork1())
            .ContinueWith((t1) => DoWork2())
            .ContinueWith(t2 => DoWork3());

我想把它放在一个循环中,这样它们就可以无限期地运行(DoWork3() 完成后,返回到DoWork1()。我尝试放入一个 while 循环,但是一旦任务完成,循环就会进入下一次迭代启动,创建大量新任务。

如果有一种方法可以退出条件以跳出循环,也许会传递一个取消令牌。

谢谢!

【问题讨论】:

  • 太棒了!让我们知道您的进展情况
  • 最终遵循@MickyD 关于使用连续等待的建议并替换了 ContinueWith 的。任何一个都有效,但 awaits 似乎更具可读性/灵活性。

标签: c# multithreading task task-parallel-library


【解决方案1】:

最简单的方法是使用 async/await:

async void DoStuff()
{
    while (true)
    {
        await Task.Factory.StartNew(() => DoWork1())
            .ContinueWith((t1) => DoWork2())
            .ContinueWith(t2 => DoWork3());
    }
}

或者你可以在最后一个任务完成后再次调用该方法,模拟一个while(true)

void DoStuff()
{
    Task.Factory.StartNew(() => DoWork1())
        .ContinueWith((t1) => DoWork2())
        .ContinueWith(t2 => DoWork3())
        .ContinueWith(t3=> DoStuff());
}

您也可以为该任务明确地Wait,但这会阻塞您正在执行的线程:

void DoStuff()
{
    while (true)
    {
        Task.Factory.StartNew(() => DoWork1())
            .ContinueWith((t1) => DoWork2())
            .ContinueWith(t2 => DoWork3())
            .Wait();
    }
}

【讨论】:

    【解决方案2】:

    您可以等待任务完成,然后再开始循环的下一次迭代。

    while(true) 
    {
        var task = Task.Factory.StartNew(() => DoWork1())
                .ContinueWith((t1) => DoWork2())
                .ContinueWith(t2 => DoWork3());
        task.Wait(); 
    }   
    

    如果没有task.Wait()(或类似机制),这些任务将被安排运行,但下一次的 while 循环将开始,而无需等待这些任务完成。

    【讨论】:

    • 虽然不错,但在这个时代,连续的内联awaits 比.ContinueWith()s 对小猫更友善
    • @MickyD 您将如何使用内联等待编写上述内容?我想知道!
    • await Task.Run(() => DoWork()); await Task.Run(() => DoWork2()); await Task.Run(() => DoWork()); 不难。还有check out the dangersContinueWith
    【解决方案3】:

    你可以这样做:

    List<Task> tasks = new List<Task>();
    
    for (int i = 0; i < 10; i++) //your loop
    {
        var task = Task.Factory.StartNew(() => DoWork1()).ContinueWith((t1) => DoWork2()).ContinueWith(t2 => DoWork3());
        tasks.Add(task);
    }
    
    Task.WaitAll(tasks.ToArray());
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-06
      • 1970-01-01
      • 1970-01-01
      • 2015-11-11
      • 2017-04-19
      • 1970-01-01
      • 2020-09-17
      相关资源
      最近更新 更多