在 C# 中通过并行性字符串名称锁定代码

问题描述 投票:0回答:1

我有以下代码:

string[] arr = ["A", "B", "B", "B", "B", "B", "C"];

var options = new ParallelOptions() { 
    MaxDegreeOfParallelism = 3 
};

Parallel.ForEach(arr, options , res =>
{
    // No double res with the same name is allowed
    // Code with res
});

我希望并行循环中的代码能够同时执行AB,并等待第一个B完成才能移动到下一个B

换句话说,不允许在同一个res上同时运行代码。

使用命名信号量,如果我想在运行时创建信号量,它不能是静态的。

如何解决这个问题?

谢谢

c# .net multithreading semaphore parallel.foreach
1个回答
0
投票

您可以通过对项目进行分组来完成此操作,然后在组上运行 Parallel.ForEach()。

代码,我在其中添加了后缀到

B
,以便我们可以区分它们:

string[] arr = ["A", "B1", "B2", "B3", "B4", "B5", "C"];
var groups = arr.GroupBy(x => x[0]).ToArray();

var options = new ParallelOptions() { MaxDegreeOfParallelism = 3 };
Parallel.ForEach(groups, options, async group =>
{
    foreach (var res in group) {
        Console.WriteLine("Start " + res);
        await Task.Delay(50 + rnd.Next(1000));
        Console.WriteLine("End   " + res);
    }
});
await Task.Delay(4000);
Console.WriteLine("Done");

工作小提琴:https://dotnetfiddle.net/t5wm1a

输出运行1:

Start A
Start B1
Start C
End   B1
Start B2
End   C
End   A
End   B2
Start B3
End   B3
Start B4
End   B4
Start B5
End   B5
Done

输出运行2:

Start C
Start B1
Start A
End   A
End   B1
Start B2
End   C
End   B2
Start B3
End   B3
Start B4
End   B4
Start B5
End   B5
Done

输出显示:

  • 在前一个
    B
    结束之前,不会开始任何
    B
  • A
    C
    与所有
    B
    并行运行。
© www.soinside.com 2019 - 2024. All rights reserved.