I have this code to start a Parallel ForEach loop:
Parallel.ForEach<ListViewItem>(filesListView.Items.Cast<ListViewItem>(), new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }, item => {
if (CallToStop == true)
{
//Code here to stop the loop!
}
internalProcessStart(item);
});
I have some code which will check if there is a call to stop the threads, and then I would like to break;
the code, but this doesn't work with Parallel.
I found the same question by someone else , but their code is slighly different to mine, and I'm not sure where to put the ParallelLoopState state
.
Thanks!
Rewrite as below
Parallel.ForEach<ListViewItem>(filesListView.Items.Cast<ListViewItem>(),
new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount },
(item, state) => {
if (CallToStop == true)
{
state.Break();
}
internalProcessStart(item);
});
Hope this helps.
I think using this overload should work:
Parallel.ForEach<ListViewItem>(filesListView.Items.Cast<ListViewItem>(), new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }, (item , state) =>
{
if (/*Stop condition here*/)
{
state.Break();
}
internalProcessStart(item);
});
Try using CancellationToken as in this example (MSDN) .
Try something like this:
CancellationTokenSource cts = new CancellationTokenSource();
// Use ParallelOptions instance to store the CancellationToken
ParallelOptions po = new ParallelOptions();
po.CancellationToken = cts.Token;
po.MaxDegreeOfParallelism = Environment.ProcessorCount;
try
{
Parallel.ForEach<ListViewItem>(filesListView.Items.Cast<ListViewItem>(), po, item => {
// po.CancellationToken.ThrowIfCancellationRequested(); //1
if (CallToStop == true)
{
//Code here to stop the loop!
cts.Cancel();
}
if (po.CancellationToken.IsCancellationRequested == false)
{
internalProcessStart(item);
}
});
}
catch (OperationCanceledException e)
{
// handle
}
finally
{
cts.Dispose();
}
Or instead of setting CallToStop = true
call cts.Cancel()
directly.
Or you can uncomment //1 and let all threds that did not finished throw OperationCanceledException (only use whenyou are stopping all parallel thread because of CallToStop = true
is caused by error).
You can even pass the cts.Token
into your internalProcessStart(item,token)
and handle what to do if you cancel when internal process is already running.
Try something like this. Conceptually, you need to pass the loopState to your lambda function.
Parallel.ForEach<int>(new List<int>(),
new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount },
(val, loopState) =>
{
if (val == 9) //enter your stopcondition here
{
loopState.Stop();
return;
}
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.