0

I have a several tasks that are run in sequence; one after the other.

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

I want to put this inside a loop so they run indefinitely (After DoWork3() is done, go back to DoWork1(). I tried putting inside a while loop, but the loop goes to the next iteration as soon the task is launched, creating a boatload of new tasks.

Would also be nice to have a way to exit condition to break out of the loop, maybe pass a cancellation token.

Thanks!

user1957413
  • 105
  • 1
  • 12
  • Great! Let us know how you go –  Mar 01 '18 at 05:32
  • 1
    Ended up following @MickyD advise on using successive awaits and replaced the ContinueWith's. Either one works, but awaits seems to more readable / flexible. – user1957413 Mar 03 '18 at 03:28

3 Answers3

2

The simplest way would be to use async/await:

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

Or you can call the method again after the last task is completed, simulating a while(true) :

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

You could also Wait for the task explicitly, but this will block the thread you are executing on:

void DoStuff()
{
    while (true)
    {
        Task.Factory.StartNew(() => DoWork1())
            .ContinueWith((t1) => DoWork2())
            .ContinueWith(t2 => DoWork3())
            .Wait();
    }
}
Titian Cernicova-Dragomir
  • 230,986
  • 31
  • 415
  • 357
1

You can wait for the task to complete before starting the next iteration of while loop.

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

Without task.Wait() (or a similar mechanism) the tasks will be scheduled to run, but the next iteration of while loop will begin without waiting for these tasks to complete.

Nisarg Shah
  • 14,151
  • 6
  • 34
  • 55
  • Though nice, in this day and age successive inline `await`s are kinder to kittens than `.ContinueWith()` –  Mar 01 '18 at 05:33
  • @MickyD how would you write the above using inline awaits? I'd like to know! – user1957413 Mar 01 '18 at 05:57
  • `await Task.Run(() => DoWork()); await Task.Run(() => DoWork2()); await Task.Run(() => DoWork());` Not hard. Also [check out the dangers](https://stackoverflow.com/a/36798058/585968) of `ContinueWith` –  Mar 01 '18 at 07:12
0

You can do something as follows:

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());
Raviraj Palvankar
  • 879
  • 1
  • 5
  • 9