1

C# では、進行中の Parallel.For ループをすぐに終了できますか。次のコードは、 loopState.Stop() が呼び出された後、ループを終了するのに最大 1 秒かかる場合があります。

static void Main(string[] args)
{
    Stopwatch watch = new Stopwatch();

    Parallel.For(0, 50, (i, loopState) =>
    {
        Console.WriteLine("Thread:" + Thread.CurrentThread.ManagedThreadId + "\tIteration:" + i);
        Thread.Sleep(1000);

        if (i == 0)
        {
            watch.Start();
            loopState.Stop();
            return;
        }
    });

    Console.WriteLine("Time Elapsed since loopState.Stop(): {0}s", watch.Elapsed.TotalSeconds);
    Console.ReadKey();
}

出力

Thread:10       Iteration:0
Thread:6        Iteration:12
Thread:11       Iteration:24
Thread:12       Iteration:36
Thread:13       Iteration:48
Thread:13       Iteration:49
Thread:12       Iteration:37
Time Elapsed since loopState.Stop(): 0.9999363s

これをより速く行う方法はありますか?ありがとう!

4

2 に答える 2

3

はい、これは可能です。並列プログラミングの質問について詳しく説明しているこの記事を見てください。これはあなたのための抜粋です:

リソースを無駄にしたくなく、[キャンセル] をクリックした直後にすべての計算を停止したい場合はどうすればよいですか? この場合、長時間実行される操作を実行するメソッド内のどこかでキャンセル トークンのステータスを定期的にチェックする必要があります。キャンセル トークンをフィールドとして宣言したので、メソッド内で簡単に使用できます。

public double SumRootN(int root)
{
    double result = 0;
    for (int i = 1; i < 10000000; i++)
    {
        tokenSource.Token.ThrowIfCancellationRequested();
        result += Math.Exp(Math.Log(i) / root);
    }
    return result;
}

従来のStoporを使用しBreakても、経験しているように、タスクがすぐにキャンセルされることはありません。MSDN のこの記事によると、

このコンテキストでは、「ブレーク」とは、現在のスレッドでの現在の反復の前にあるすべてのスレッドでのすべての反復を完了し、ループを終了することを意味します。「停止」とは、都合のよいときにすべての反復を停止することを意味します。

そのため、従来の方法を使用してすぐに停止することはできません。最初に述べたような方法を使用する必要があります。

これがお役に立てば幸いです!

于 2013-02-06T01:26:47.467 に答える
1

問題はループ本体の実行時間です。 loopState.Stop()新しいループ反復を最初から停止し、現在実行中の反復が完了するのを待ちます。

于 2013-02-06T01:29:08.770 に答える