【问题标题】:How Define Counter Inside Parallel.Foreach And Stop That Loop In A Specific Number如何在 Parallel.Foreach 中定义计数器并以特定数字停止该循环
【发布时间】:2012-09-25 13:33:22
【问题描述】:

如何在 Parallel.Foreach 中定义计数器并停止特定数量的战利品?
我问这个问题是因为 Parallel.ForEach 中的计数器在常规操作中不起作用。
请看这个小例子:

static void Main(string[] args)
{
    int Count_Step = -1;
    string[] lines = new string[] 
    { 
        "0",
        "1",
        "2",
        "3",
        "4",
        "5",
        "6",
        "7",
        "8",
        "9",
        "10",
        "11",
        "12",
        "13",
        "14",
        "15",
        "16",
        "17",
        "18",
        "19"
    };

    List<string> list_lines = new List<string>(lines);

    ParallelOptions parallelOptions = new ParallelOptions();
    parallelOptions.MaxDegreeOfParallelism = 3;

    Parallel.ForEach(list_lines, parallelOptions, (line, state, index) =>
    {
        if (Count_Step == 10)
            state.Stop();
        Count_Step++;
        Console.WriteLine(index + " : " + line + " : " + Count_Step);
        //Thread.Sleep(5000);
    });

    Console.ReadLine();
}

我想要输出 10 行,而不是更多!
我该怎么做?

提前致谢

【问题讨论】:

  • 您是只想并行处理列表中的前 10 项,还是只想并行处理任意 10 项,然后在完成 10 项后停止?
  • 任意10个项目并行,然后在你完成10个后停止

标签: c# .net-4.0 console-application parallel.foreach


【解决方案1】:

如果您只想输出 10 行,请改为这样做,

static void Main(string[] args)
{
    var lines = new List<string> 
    { 
        "0",
        "1",
        "2",
        "3",
        "4",
        "5",
        "6",
        "7",
        "8",
        "9",
        ...
    };

    var parallelOptions = new ParallelOptions
        {        
            MaxDegreeOfParallelism = 3
        };

    Parallel.ForEach(lines.Take(10), parallelOptions, (line, index) =>
    {
        Console.WriteLine("{0} : {1}", index, line);
        ////Thread.Sleep(5000);
    });

    Console.ReadLine();
}

或者

static void Main(string[] args)
{
    var lines = new List<string> 
    { 
        "0",
        "1",
        "2",
        "3",
        "4",
        "5",
        "6",
        "7",
        "8",
        "9",
        ...
    };

    var parallelOptions = new ParallelOptions
        {        
            MaxDegreeOfParallelism = 3
        };

    Parallel.For(0, 9, parallelOptions, i =>
    {
        Console.WriteLine("{0} : {1}", i, lines[i]);
        ////Thread.Sleep(5000);
    });

    Console.ReadLine();
}

甚至

static void Main(string[] args)
{
    var lines = new List<string> 
    { 
        "0",
        "1",
        "2",
        "3",
        "4",
        "5",
        "6",
        "7",
        "8",
        "9",
        ...
    };

    Enumerable.Range(0, 10).AsParallel().WithDegreeOfParallelism(3).ForAll(i =>
    {
        Console.WriteLine("{0} : {1}", i, lines[i]);
        ////Thread.Sleep(5000);
    }

    Console.ReadLine();
}

如果您真的希望您的并行迭代更新循环外的某些值,那么您需要确保更改变量的所有更新和读取都是线程安全的。

如果你要增加一个整数,你可以这样做。

var stepCount = 0;

Enumerable.Range(0, 10).AsParallel().WithDegreeOfParallelism(3).ForAll(i =>
    {
        var thisCount = Interlocked.Increment(ref stepCount);
        Console.WriteLine("{0} : {1} : {2}", i, lines[i], thisCount);
        ////Thread.Sleep(5000);
    }

Console.ReadLine();

但是,thisCount 的输出在控制台窗口中并不保证是连续的,两行之间可能存在线程切换。

如果你想做一些更复杂的事情,比如取消部分处理,你应该看看BlockingCollection。

【讨论】:

  • 我们无法更改该数组 :) 这只是我在 Q 中所说的一个示例。我希望它用于其他情况。
  • 感谢您的编辑。但我会在里面得到那个 9 数字(在其他情况下)-> 我该怎么办?
  • @MoonLight 我不明白,你说的“那个9号”是什么意思,你指的是Count_Step吗?
  • @MoonLight 我添加了一个带有外部计数器的示例。
  • 如何将(line, index) 翻译成VB in? Parallel.ForEach(lines.Take(10), parallelOptions, (line, index) => { Console.WriteLine("{0} : {1}", index, line); ////Thread.Sleep(5000) ; });
【解决方案2】:

试试Parallel.For()

Parallel.For Method

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-23
    • 2018-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多