Postupy: Zrušení smyček Parallel.For nebo ForEach
Tyto Parallel.For metody Parallel.ForEach podporují zrušení prostřednictvím použití tokenů zrušení. Další informace o zrušení obecně naleznete v tématu Zrušení. V paralelní smyčce zadáte CancellationToken metodu v parametru ParallelOptions a pak uzavřete paralelní volání do bloku try-catch.
Příklad
Následující příklad ukazuje, jak zrušit volání Parallel.ForEach. Stejný přístup můžete použít i u Parallel.For volání.
namespace CancelParallelLoops
{
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static void Main()
{
int[] nums = Enumerable.Range(0, 10_000_000).ToArray();
CancellationTokenSource cts = new();
// Use ParallelOptions instance to store the CancellationToken
ParallelOptions options = new()
{
CancellationToken = cts.Token,
MaxDegreeOfParallelism = Environment.ProcessorCount
};
Console.WriteLine("Press any key to start. Press 'c' to cancel.");
Console.ReadKey();
// Run a task so that we can cancel from another thread.
Task.Factory.StartNew(() =>
{
if (Console.ReadKey().KeyChar is 'c')
cts.Cancel();
Console.WriteLine("press any key to exit");
});
try
{
Parallel.ForEach(nums, options, (num) =>
{
double d = Math.Sqrt(num);
Console.WriteLine("{0} on {1}", d, Environment.CurrentManagedThreadId);
});
}
catch (OperationCanceledException e)
{
Console.WriteLine(e.Message);
}
finally
{
cts.Dispose();
}
Console.ReadKey();
}
}
}
' How to: Cancel a Parallel.For or ForEach Loop
Imports System.Threading
Imports System.Threading.Tasks
Module CancelParallelLoops
Sub Main()
Dim nums() As Integer = Enumerable.Range(0, 10000000).ToArray()
Dim cts As New CancellationTokenSource
' Use ParallelOptions instance to store the CancellationToken
Dim po As New ParallelOptions
po.CancellationToken = cts.Token
po.MaxDegreeOfParallelism = System.Environment.ProcessorCount
Console.WriteLine("Press any key to start. Press 'c' to cancel.")
Console.ReadKey()
' Run a task so that we can cancel from another thread.
Dim t As Task = Task.Factory.StartNew(Sub()
If Console.ReadKey().KeyChar = "c"c Then
cts.Cancel()
End If
Console.WriteLine(vbCrLf & "Press any key to exit.")
End Sub)
Try
' The error "Exception is unhandled by user code" will appear if "Just My Code"
' is enabled. This error is benign. You can press F5 to continue, or disable Just My Code.
Parallel.ForEach(nums, po, Sub(num)
Dim d As Double = Math.Sqrt(num)
Console.CursorLeft = 0
Console.Write("{0:##.##} on {1}", d, Thread.CurrentThread.ManagedThreadId)
End Sub)
Catch e As OperationCanceledException
Console.WriteLine(e.Message)
Finally
cts.Dispose()
End Try
Console.ReadKey()
End Sub
End Module
Pokud token, který signalizuje zrušení, je stejný token, který je zadán v ParallelOptions instanci, pak paralelní smyčka vyvolá jeden OperationCanceledException při zrušení. Tím se okamžitě zastaví spuštění všech iterací, protože je vyvolán výjimka. Pokud některé jiné tokeny způsobí zrušení, smyčka vyvolá AggregateExceptionOperationCanceledExceptionInnerException
jako .