C#-并行异步运行代码

C#-并行异步运行代码,c#,asynchronous,task-parallel-library,C#,Asynchronous,Task Parallel Library,我有一个C#控制台应用程序,我正在使用它进行实验。我有一些代码块,我知道我想1)异步2)并行运行,3)在每个代码块完成后运行一些共享清理代码 我需要异步运行这些块,因为每个块都在调用一个web服务。出于性能原因,我需要并行运行每个块,并且没有任何块依赖于其他块。最后,我有大量的清理和日志代码,希望在每个块完成时运行这些代码。因此,此代码是共享的 我被困在如何做到这一点。到目前为止,我已经了解了以下C#概念: 1) -优点:擅长异步运行代码缺点:a)我没有找到定义任务并将其传递给共享方法以便运行清

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

我需要异步运行这些块,因为每个块都在调用一个web服务。出于性能原因,我需要并行运行每个块,并且没有任何块依赖于其他块。最后,我有大量的清理和日志代码,希望在每个块完成时运行这些代码。因此,此代码是共享的

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

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

2) -优点:a)可以内联定义代码块,即
var myAction=(Action)(()=>{})。b) 可以轻松地将参数传递到
操作
。缺点:似乎不是异步运行操作的方法,因此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
}
如何以异步、并行的方式运行代码块,使我能够在完成所有操作后执行一些共享清理代码?我觉得我总是得到三个要求中的两个,但却很难得到所有三个


谢谢你的帮助

您可以创建一个需要并行执行的任务列表,然后使用
Task异步等待所有任务完成。所有
static方法:

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

RoutineA
RoutineB
可以是
async
函数,返回
Task
。请注意,我们不等待这些调用,因此调用线程在启动
RoutineA
后继续触发
RoutineB
,您可以执行。当所有的以并行和异步方式运行某个任务时

例如

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);
Task a=AsyncTaskA();
任务b=异步任务b();
任务c=AsyncTaskC();
列出所有任务=新建列表();
所有任务。添加(a);
所有任务。添加(b);
所有任务。添加(c);
//这将异步并行运行所有任务,并等待所有任务完成
等待任务。WhenAll(所有任务);

我会使用
任务。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();
var stopwatch=new stopwatch();
秒表。开始();
操作日志时间=(标签)=>Console.WriteLine($“{label}:{stopwatch.appeased.Seconds}以秒为单位”);
var taskList=新列表();
taskList.Add(Task.Run(()=>{DoWork();logTime(“Task 1”);});
taskList.Add(Task.Run(()=>{DoWork();logTime(“task2”);});
taskList.Add(Task.Run(()=>{DoWork();logTime(“task3”);});
taskList.Add(Task.Run(()=>{DoWork();logTime(“task4”);});
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”);});
wait Task.Run(()=>Task.WaitAll(taskList.ToArray());
秒表;
var timeRan=秒表。已用时间。秒;
//记录时间
日志时间(“总时间”);
Console.ReadLine();

这将阻止调用线程,因为Task.WaitAll是同步方法。是,这是正确的。我会更新的,谢谢。但是这种方法不会为每个单独的任务计时。它只计算所有任务的总时间。我将更新Anwser。不过,这种方法不会计算单个任务的时间。我的挑战是,我希望在每个任务运行后运行Cleanup方法。不是在所有任务都运行之后。@ZachTempleton,那么在每个任务中添加清理调用,那么到底是什么问题呢?