c# - How to catch an OperationCanceledException when using ContinueWith -
i have code i'm downgrading .net 4.5's lovely async
, await
keywords .net 4.0. i'm using continuewith
create continuation similar way await
works.
basically, old code was:
var tokensource = newcancellationtokensource(); var mytask = task.run(() => { return mystaticclass.dostuff(tokensource.token); }, tokensource.token); try { var result = await mytask; dostuffwith(result); } catch (operationcanceledexception) { // cancel gracefully. }
(as 1 might expect, mystaticclass.dostuff(token)
regularly calls token.throwifcancellationrequested()
.)
my new code looks this:
var tokensource = new cancellationtokensource(); try { task.factory.startnew(() => { return mystaticclass.dostuff(tokensource.token); }, tokensource.token) .continuewith(task => { var param = new object[1]; param[0] = task.result; // need use invoke here because "dostuffwith()" ui stuff. invoke(new mydelegate(dostuffwith, param)); }); } catch (operationcanceledexception) { // cancel gracefully. }
however, operationcanceledexception
never caught. what's going on? put try/catch block?
cancellation handled differently other exceptions. basically, can use pattern:
task.factory.startnew(() => { // task }, tokensource.token) .continuewith(task => { // normal stuff }, taskcontinuationoptions.onlyonrantocompletion) .continuewith(task => { // handle cancellation }, taskcontinuationoptions.onlyoncanceled) .continuewith(task => { // handle other exceptions }, taskcontinuationoptions.onlyonfaulted);
or alternative one:
task.factory.startnew(() => { // task }, tokensource.token) .continuewith(task => { switch (task.status) { case taskstatus.rantocompletion: // normal stuff break; case taskstatus.canceled: // handle cancellation break; case taskstatus.faulted: // handle other exceptions break; } });
in case, you're not catching because:
task.factory.startnew
returns , succeeds.- your continuation runs
- accessing
task.result
throwsaggregateexception
since task canceled the exception not handled since it's thrown thread pool thread. oops. happens next depends on framework version:
- in .net < 4.5, process terminated failing task finalized, since have unobserved exception.
- in .net >= 4.5, exception silently dropped.
Comments
Post a Comment