C# - 并行异步运行代码

时间:2018-04-30 12:20:33

标签: c# asynchronous task-parallel-library

我有一个C#控制台应用程序,我用它来进行实验。我有一些代码块,我知道我想运行1)异步2)并行3)每个块完成时运行一些共享清理代码。

我需要异步运行块,因为每个块都在调用Web服务。出于性能原因,我需要并行运行每个块,并且没有块依赖于另一个块。最后,我有大量的清理和日志记录代码,我想在每个块完成时运行。因此,此代码是共享的。

我被困在如何做到这一点。到目前为止,我已经看了下面的C#概念:

1)Tasks - 优点:擅长异步运行代码缺点:a)我没有看到定义任务并将其传递给共享方法的方法,以便我可以运行清理代码。 b)我没有看到将参数传递给任务的好方法

2)Actions - 优点:a)可以定义内联的代码块,即var myAction = (Action)(() => { });。 b)可以轻松地将参数传递给Action。缺点:似乎不是异步运行动作的一种方式,因此b)不确定我可以并行运行动作。

在我写这个问题时,我很清楚我错过了什么。乍一看,任务似乎是正确的道路。但是,我确实感到困惑于

public void RunTaskInParallel(Task task)
{
  var startTime = DateTime.UtcNow;

  // Execute task code

  var executionTime = DateTime.UtcNow.Subtract(startTime);
  // Log the execution time    

  // Execute Clean-up Code
}

如何以并行方式异步运行代码块,以便在完成所有操作后允许我执行一些共享清理代码?我觉得我总是得到三分之二的要求,但努力争取全部三个。

感谢您的帮助!

3 个答案:

答案 0 :(得分:0)

您可以创建一个需要并行执行的任务列表,然后异步等待所有任务都以Task.WhenAll静态方法完成:

await Task.WhenAll(new []{ RoutineA(), RoutineB()});
Cleanup();

RoutineARoutineB可以是async个函数,返回Task。请注意,我们不会await这些调用 - 因此调用线程在启动RoutineB后会继续触发RoutineA

答案 1 :(得分:0)

您可以 .WhenAll 以并行和异步方式运行某项任务。

例如

Task a = AsyncTaskA();
Task b = AsyncTaskB();
Task c = AsyncTaskC();
List<Task> AllTasks = new List<Task>();
AllTasks.Add(a);
AllTasks.Add(b);
AllTasks.Add(c);
// this will run all your tasks async and parallel and also wait until everything is done
await Task.WhenAll(AllTasks);

答案 2 :(得分:-1)

我会使用Task.WaitAll,它看起来像:

         var stopwatch = new Stopwatch();
        stopwatch.Start();

        Action<string> logTime = (label) => Console.WriteLine($"{label}: {stopwatch.Elapsed.Seconds} in Seconds");


        var taskList = new List<Task>();
        taskList.Add(Task.Run(() => { DoWork(); logTime("Task 1");}));
        taskList.Add(Task.Run(() => { DoWork(); logTime("Task 2"); }));
        taskList.Add(Task.Run(() => { DoWork(); logTime("Task 3"); }));
        taskList.Add(Task.Run(() => { DoWork(); logTime("Task 4"); }));
        taskList.Add(Task.Run(() => { DoWork(); logTime("Task 5"); }));
        taskList.Add(Task.Run(() => { DoWork(); logTime("Task 6"); }));
        taskList.Add(Task.Run(() => { DoWork(); logTime("Task 7"); }));
        taskList.Add(Task.Run(() => { DoWork(); logTime("Task 8"); }));

        await Task.Run(()=>Task.WaitAll(taskList.ToArray()));
        stopwatch.Stop();

        var timeRan = stopwatch.Elapsed.Seconds;
        //log time
        logTime("Total Time");
        Console.ReadLine();
相关问题