c# - Why is TaskCanceledException thrown and does not always breaks into the debugger -
i'm digging async-await
mechanism , observed throwing of taskcanceledexception
can't explain yet.
in sample below (self contained) have statement
await task.run(() => null);
i know statement on useless isolated issue, real code has logic , returns null in cases.
why throw taskcanceledexception
? if homecoming arbitrary number (5 in below example) not throw.
furthermore if await
method debugger of vs breaks if don't await
message written output window of vs.
internal class programme { private static void main(string[] args) { var testasync = new testasync(); // exception thrown debugger not step in. message logged output window testasync.testasyncexceptiononlyintheoutputwindow(); // exception thrown , debugger breaks testasync.testasyncexceptionbreaksintothedebugger(); console.readkey(); } } internal class testasync { public async void testasyncexceptiononlyintheoutputwindow() { testnullcase(); } public async void testasyncexceptionbreaksintothedebugger() { await testnullcase(); } private static async task testnullcase() { // not throw taskcanceledexception await task.run(() => 5); // throw taskcanceledexception await task.run(() => null); } }
taskcanceledexception
the reason task.run(() => null)
returns canceled task rests in overload resolution. compiler chooses static task run(func<task> function)
, not static task<tresult> run<tresult>(func<tresult> function)
1 may expect. acts if you're calling async
delegate, in case you're not. results in task.run
"unwrapping" homecoming value (null
) task in turn cancel task.
the specific code responsible in processinnertask
private method in unwrappromise<tresult>
(inherits task<tresult>
) class:
private void processinnertask(task task) { // if inner task null, proxy should canceled. if (task == null) { trysetcanceled(default(cancellationtoken)); _state = state_done; // ... , record done } // ... }
you can tell compiler not telling compiler not returning task
:
var result = await task.run(() => (object)null); // not throw exception. result null
exception handling the difference between 2 methods in testasyncexceptiononlyintheoutputwindow
don't await
faulted task , exception stored in task never rethrown.
you can create debugger break in both methods checking thrown column on common language runtime exceptions in settings (debug => exceptions):
c# .net task-parallel-library async-await
No comments:
Post a Comment