c# - Why isn't a CancellationToken included in the Task<T> monad? -
task<t>
neatly holds "has started, might finished" computation, can composed other tasks, mapped functions, etc. in contrast, f# async
monad holds "could start later, might running now" computation, along with cancellationtoken
. in c#, typically have thread cancellationtoken
through every function works task
. why did c# team elect wrap computation in task
monad, not cancellationtoken
?
more or less, encapsulated implicit use of cancellationtoken
c# async
methods. consider this:
var cts = new cancellationtokensource(); cts.cancel(); var token = cts.token; var task1 = new task(() => token.throwifcancellationrequested()); task1.start(); task1.wait(); // task in faulted state var task2 = new task(() => token.throwifcancellationrequested(), token); task2.start(); task2.wait(); // task in cancelled state var task3 = (new func<task>(async() => token.throwifcancellationrequested()))(); task3.wait(); // task in cancelled state
for non-async lambda, had explicitly associate token
task2
cancellation propagate correctly, providing argument new task()
(or task.run
). async
lambda used task3
, happens automatically part of async/await
infrastructure code.
moreover, any token
propagate cancellation async
method, while non-async computational new task()
/task.run
lambda has same token passed task constructor or task.run
.
of course, still have call token.throwifcancellationrequested()
manually implement cooperative cancellation pattern. can't answer why c# , tpl teams decided implement way, guess aimed not over-complicate syntax of async/await
yet keep flexible enough.
as f#, haven't looked @ generated il code of asynchronous workflow, illustrated in tomas petricek's blog post linked. yet, far understand, token automatically tested @ locations of workflow, corresponding await
in c# (by analogy, might calling token.throwifcancellationrequested()
manually after every await
in c#). means cpu-bound work still won't cancelled immediately. otherwise, f# have emit token.throwifcancellationrequested()
after every il instruction, quite substantial overhead.
Comments
Post a Comment