C# 并行执行一对任务

C# 并行执行一对任务,c#,asp.net,.net,task-parallel-library,C#,Asp.net,.net,Task Parallel Library,有两个任务是开/关执行的,我想创建这些任务(对)的列表并并行执行它们。含义:每个任务封装TaskA和TaskB,TaskB总是等待TaskA首先完成。因此,我应该以并行执行TaskA/TaskB的“set”结束 Task={TaskA,TaskB},{TaskA,TaskB},{TaskA,TaskB} :并行执行这3组任务 主要内容: 我认为产出应该是: ended TaskA ended TaskB ended TaskA ended TaskB // etc.. 另外,尝试了这个,但仍然

有两个任务是开/关执行的,我想创建这些任务(对)的列表并并行执行它们。含义:每个任务封装TaskA和TaskB,TaskB总是等待TaskA首先完成。因此,我应该以并行执行TaskA/TaskB的“set”结束

Task={TaskA,TaskB},{TaskA,TaskB},{TaskA,TaskB} :并行执行这3组任务

主要内容:

我认为产出应该是:

ended TaskA
ended TaskB
ended TaskA
ended TaskB
// etc..
另外,尝试了这个,但仍然存在相同的问题:

static void StartTask()
{
    Task task = TaskA().ContinueWith(x => TaskB().Wait(), TaskContinuationOptions.OnlyOnRanToCompletion);
}
编辑1:

    Parallel.For(1, taskCount, (i, state) =>
    {
        TaskA().ContinueWith(x => TaskB().Wait(), TaskContinuationOptions.OnlyOnRanToCompletion);
    });
我认为输出应该是:

不,“平行”不是这个意思。如果你要开始三对,那么我希望你已经看到了输出

也就是说,代码中有一些东西没有意义。首先,区分“并行”(多线程)和“并发”(同时做多件事情)。看起来您的任务自然是异步的,所以让我们使用异步编程而不是线程来重写:

  • Wait
    替换为
    Wait
  • 摆脱
    任务。运行
只需将
TaskA
TaskB
组合成一个新的“配对任务”就更容易了:

现在您只需要同时运行这些“配对任务”中的3个。旧代码使用任务构造函数,然后并行启动任务——这几乎是完全错误的,即使我们想要并行。我们没有;我们需要异步并发

异步并发通常是通过
任务实现的。当所有
完成时:

List<Task> tasks = new List<Task>();
int taskCount = 3;

for (var i = 0; i < taskCount; i++)
  tasks.Add(PairTaskAsync());

await Task.WhenAll(tasks);
我认为输出应该是:

不,“平行”不是这个意思。如果你要开始三对,那么我希望你已经看到了输出

也就是说,代码中有一些东西没有意义。首先,区分“并行”(多线程)和“并发”(同时做多件事情)。看起来您的任务自然是异步的,所以让我们使用异步编程而不是线程来重写:

  • Wait
    替换为
    Wait
  • 摆脱
    任务。运行
只需将
TaskA
TaskB
组合成一个新的“配对任务”就更容易了:

现在您只需要同时运行这些“配对任务”中的3个。旧代码使用任务构造函数,然后并行启动任务——这几乎是完全错误的,即使我们想要并行。我们没有;我们需要异步并发

异步并发通常是通过
任务实现的。当所有
完成时:

List<Task> tasks = new List<Task>();
int taskCount = 3;

for (var i = 0; i < taskCount; i++)
  tasks.Add(PairTaskAsync());

await Task.WhenAll(tasks);

为什么不从taska的末尾运行taskb呢?我想这就是我在做的私有静态异步任务taska(){await Task.Delay(2000);Console.WriteLine(“ended taska”);taskb();}我不能修改taska或taskb。TaskA必须在TaskB启动之前完成,但顺便说一句,当前输出没有问题。因为您并行运行集合,A1、A2、A3并行启动,当A1完成时,A2和A3很可能同时完成,那么您会看到B1、B2和B3并行启动。为什么不从taska的末尾运行taskb呢?我想这就是我在做的私有静态异步任务taska(){wait Task.Delay(2000);Console.WriteLine(“已结束的TaskA”);TaskB();}我无法修改TaskA或TaskB。TaskA必须在TaskB启动之前完成,但顺便说一句,当前输出没有问题。因为您并行运行集合,A1、A2、A3并行启动,当A1完成时,A2和A3很可能同时完成,然后您会看到B1、B2和B3并行启动。Stephen,请您在代码中添加注释以使其更清晰吗?。PairTaskAsync何时启动?你什么时候加?或者在等待线?还有,我可以把秒表放在哪里?要知道TaskA和TaskB在一对中需要多长时间才能完成?有没有一本书可以用简单易懂的方式解释异步/并发/并行性?@BobSwanson:任务返回“热”状态,即,
PairTaskAsync
在调用它时开始。您可以在
PairTaskAsync
中放置秒表来测量a和B。我有一个。Stephen,请您在代码中添加注释以使其更清晰吗?。PairTaskAsync何时启动?你什么时候加?或者在等待线?还有,我可以把秒表放在哪里?要知道TaskA和TaskB在一对中需要多长时间才能完成?有没有一本书可以用简单易懂的方式解释异步/并发/并行性?@BobSwanson:任务返回“热”状态,即,
PairTaskAsync
在调用它时开始。您可以在
PairTaskAsync
内放置秒表来测量a和B。我有一个。
    Parallel.For(1, taskCount, (i, state) =>
    {
        TaskA().ContinueWith(x => TaskB().Wait(), TaskContinuationOptions.OnlyOnRanToCompletion);
    });
static async Task PairTaskAsync()
{
  await TaskA();
  await TaskB();
}
List<Task> tasks = new List<Task>();
int taskCount = 3;

for (var i = 0; i < taskCount; i++)
  tasks.Add(PairTaskAsync());

await Task.WhenAll(tasks);
await Task.WhenAll(Enumerable.Range(0, 3).Select(_ => PairTaskAsync()));