4

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行が必要ですが、それ以上は必要ありません。
どうやってやるの?

前もって感謝します

4

2 に答える 2

11

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コンソール ウィンドウでの出力が連続しているとは限りません。2 つの行の間でスレッドの切り替えが発生する可能性があります。

処理を途中でキャンセルするなど、より高度な処理を行いたい場合は、BlockingCollectionを参照してください。

于 2012-09-25T13:44:02.287 に答える
4

試すParallel.For()

Parallel.For メソッド

于 2012-09-25T13:47:49.313 に答える