简体   繁体   中英

How to delay 'hot' tasks so they can processed in a set order

Say I have a set of tasks:

        var task1 = DoThisAsync(...);
        var task2 = DoThatAsync(...);
        var task3 = DoOtherAsync(...);
        var taskN...

I am looking for a way to process a set of tasks in order (determined by place in containing collection say), but to have the tasks only run/start when its their turn and not before - and have all of that wrapped up in its own task.

Problem constraints / details are:

  1. These tasks need to be performed in a certain order ietask1, task2,...
  2. The previous task must complete asynchronously before the next can start
  3. The number of tasks is variable
  4. A different set of tasks may be nominated each time code is run
  5. The order and number of tasks is known in advance.

The main problem is that as soon as I call the relevant method (like DoThis()...) to return each task, that task is already 'hot' or running, violating (2) above.

I have tried working with.ContinueWith(..) , but if I call each of tasks like above to set the continuations or add them to a list or collection they've already started.

Not sure if Lazy < T > might help but can't see how at present?

Hope this makes sense as I'm fairly new to async / await / tasks.

Many thanks in advance.

Calling a method runs code. If you want an object that will call this method later , then use a delegate.

In this case, you could use Func<Task> , which is an asynchronous delegate. A list of these should suffice:

// Build the list of operations in order.
var operations = new List<Func<Task>>();
operations.Add(() => DoThisAsync(...));
operations.Add(() => DoThatAsync(...));
operations.Add(() => DoOtherAsync(...));

// Execute them all one at a time.
foreach (var operation in operations)
  await operation();

you can simply create tasks with its constructor and then, call execution with .Start() methods.

Here an example:

var taskList = InitQueue();
foreach (var t in taskList.OrderBy(i => i.Order))
{
    //Here I can skedule an existing task
    t.TaskToRun.Start();
    t.TaskToRun.Wait();
    Console.WriteLine($"Task {t.Order} has finished its job");
}


public class TaskQueue : List<TaskItem>
{
}

public class TaskItem
{
    public int Order { get; set; }
    public Task TaskToRun { get; set; }
}

private static TaskQueue InitQueue()
{
    var queue = new TaskQueue();
    queue.Add(new TaskItem
    {
        Order = 1,
        TaskToRun = new Task(() =>
        {
            Task.Delay(500);
            Console.WriteLine("Hello from task 1");
        })
    });
    queue.Add(new TaskItem
    {
        Order = 4,
        TaskToRun = new Task(() => Console.WriteLine("Hello from task 4"))
    });
    queue.Add(new TaskItem
    {
        Order = 3,
        TaskToRun = new Task(() =>
        {
            Task.Delay(5000);
            Console.WriteLine("Hello from task 3");
        })
    });
    queue.Add(new TaskItem
    {
        Order = 2,
        TaskToRun = new Task(() => Console.WriteLine("Hello from task 2"))
    });

    return queue;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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