I ran a Parallel.ForEach loop to do some work, but I got into a problem due to an unhandled exception while I thought I was handling the cancellation.
To try to understand the problem, I made a simple test setup in winform. It has a start button, a cancel button and a label for output.
Code:
public partial class Form1 : Form { CancellationTokenSource cts = new CancellationTokenSource(); public Form1() { InitializeComponent(); } private async void button1_Click(object sender, EventArgs e) { output.Text = "Running"; try { var runTask = Task<string>.Factory.StartNew(() => Run()); await runTask; this.output.Text = runTask.Result; } catch(Exception ex) { throw ex; } } private string Run() { int useThreads = Environment.ProcessorCount - 2 < 1 ? 1 : Environment.ProcessorCount - 2; ParallelOptions options = new ParallelOptions() { MaxDegreeOfParallelism = useThreads, CancellationToken = cts.Token }; options.CancellationToken.Register(() => ActionOnCancel()); List<int> somelist =new List<int>(); for(int i = 0; i < 100; i++) somelist.Add(i); Parallel.ForEach(somelist, options, (row, loopstate) => { if(loopstate.ShouldExitCurrentIteration || loopstate.IsExceptional) loopstate.Stop(); Thread.Sleep(1000); }); return "Done"; } private void ActionOnCancel() { output.Text= "Cancelled"; } private void button2_Click(object sender, EventArgs e) { cts.Cancel(); }
When I run the program and press the cancel button (to start button2_Click), I continue to get this error:
An exception of type "System.OperationCanceledException" occurred in mscorlib.dll, but was not processed in the user code
Additional Information: The operation has been canceled.
If there is a handler for this exception, the program can safely continue.
And the debugger allocates the Parallel.ForEach section. But why??? I thought I reacted correctly to cancellation via a CancellationToken.
The exception message in ex does not give me any clarity: "{" The operation was canceled. "}" Uh ... yes ... that was the intention ...
What am I missing? Yours faithfully,
Matthijs
source share