방법: Parallel.For 또는 ForEach 루프 취소
Parallel.For 및 Parallel.ForEach 메서드는 취소 토큰을 사용한 취소 기능을 지원합니다. 일반적인 취소에 대한 자세한 내용은 취소를 참조하십시오. 병렬 루프에서는 ParallelOptions 매개 변수로 메서드에 CancellationToken을 제공한 다음 병렬 호출을 try-catch 블록 안에 넣습니다.
예제
다음 예제에서는 Parallel.ForEach에 대한 호출을 취소하는 방법을 보여 줍니다. Parallel.For 호출에도 동일한 방법을 적용할 수 있습니다.
' 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)
po.CancellationToken.ThrowIfCancellationRequested()
End Sub)
Catch e As OperationCanceledException
Console.WriteLine(e.Message)
End Try
Console.ReadKey()
End Sub
End Module
namespace CancelParallelLoops
{
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static void Main()
{
int[] nums = Enumerable.Range(0, 10000000).ToArray();
CancellationTokenSource cts = new CancellationTokenSource();
// Use ParallelOptions instance to store the CancellationToken
ParallelOptions po = 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.
Task.Factory.StartNew(() =>
{
if (Console.ReadKey().KeyChar == 'c')
cts.Cancel();
Console.WriteLine("press any key to exit");
});
try
{
Parallel.ForEach(nums, po, (num) =>
{
double d = Math.Sqrt(num);
Console.WriteLine("{0} on {1}", d, Thread.CurrentThread.ManagedThreadId);
po.CancellationToken.ThrowIfCancellationRequested();
});
}
catch (OperationCanceledException e)
{
Console.WriteLine(e.Message);
}
Console.ReadKey();
}
}
}
취소를 알리는 토큰이 ParallelOptions 인스턴스에 지정된 토큰과 동일한 경우 병렬 루프에서는 취소에 대해 단일 OperationCanceledException을 throw합니다. 다른 토큰에 의해 취소가 발행한 경우 루프에서는 AggregateException을 throw하고 OperationCanceledException을 InnerException으로 throw합니다.