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 throws aggregateexception 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

Popular posts from this blog

c++ - Difference between pre and post decrement in recursive function argument -

php - Nothing but 'run(); ' when browsing to my local project, how do I fix this? -

php - How can I echo out this array? -