c# - ParallelFor not cancelling all threads immediately if condition met -
code waits until running tasks have finished before operationcancelledexception
thrown.
i program stop on condition being true.
static void main() { // want break out of parallel.for when condition occurs var cts = new cancellationtokensource(); var po = new paralleloptions(); po.cancellationtoken = cts.token; long countertotal = 0; try { // want have sum of counts @ end parallel.for<long>(1, 26, po, () => 0, delegate(int i, parallelloopstate state, long countersubtotal) { po.cancellationtoken.throwifcancellationrequested(); console.writeline(i.tostring()); (int k = 0; k < 1000000000; k++) { countersubtotal++; if (i == 4 && k == 900000000) { cts.cancel(); // break out here } } return countersubtotal; }, (x) => interlocked.add(ref countertotal, x) ); } catch (operationcanceledexception e) { console.writeline("cancelled"); console.writeline("total iterations across threads {0}", string.format("{0:n0}", countertotal)); console.readline(); } }
i found putting breakpoint on cts.cancel()
, in catch demonstrates happening.
have looked @ state.stop
too.
this simplified version of other code.
perhaps parallel.for
isn't ideal things long running inside method if want break out immediately.
update2: code works expected , gives total
static void main() { // want break out of parallel.for when condition occurs var cts = new cancellationtokensource(); var po = new paralleloptions(); po.cancellationtoken = cts.token; long countertotal = 0; try { // want have sum of counts @ end // using type param here make countersubtotal long parallel.for<long>(1, 26, po, () => 0, delegate(int i, parallelloopstate state, long countersubtotal) { console.writeline(i.tostring()); // 1 billion (int k = 0; k < 1000000000; k++) { //po.cancellationtoken.throwifcancellationrequested(); if (po.cancellationtoken.iscancellationrequested) { return countersubtotal; } countersubtotal++; if (i == 4 && k == 400000000) { console.writeline("inner cancelled"); cts.cancel(); } } return countersubtotal; }, (x) => interlocked.add(ref countertotal, x) ); } catch (operationcanceledexception e) { console.writeline("cancelled"); console.writeline("total iterations across threads {0}", string.format("{0:n0}", countertotal)); console.readline(); } }
if want break more "immediately" need check cancellation token inside of inner for. now, check cancel before entering, after won't @ token again.
for (int k = 0; k < 1000000000; k++) { po.cancellationtoken.throwifcancellationrequested(); countersubtotal++; if (i == 4 && k == 900000000) { cts.cancel(); } }
Comments
Post a Comment