I'm considering using the pplx component of Casablanca as a cross-platform asynchronous task library, targeting Windows family, OSX/iOS, Linux and Android. There a lot of great features in pplx, and some issues I would need to work around (platform support,
static library) - but the real show-stopper is that task cancellation is not yet implemented.
I know there is an issue already logged for this, and may be in future release plans, but I am looking to start using pplx (or not) asap.
How difficult would it be for me to implement task cancellation properly? Has anyone in the community tried to do this already? From the code, there are two obvious functions that need implemented - _TaskCollectionImpl::_Cancel and _TaskCollectionImpl::_Is_cancellation_requested
- but it is not clear what the semantics of these two functions should be, or if there are any other missing pieces of the jigsaw.
Any insights, guidance, or prototype code would be invaluable.
Feb 5, 2014 at 3:37 AM
Edited Feb 5, 2014 at 3:37 AM
Thanks for being interested in this project.
Firstly, I want to clarify that pplx does support cancellation in certain manner (Not the ConcRT way, if you know what it is).
To explain that, let's look at all cancellation semantics we support and don't support in pplx:
- support cancellation token / cancellation token sources as a way to passing cancellation signals.
- support canceling current running task by calling cancel_current_task() on the running thread.
- support cancel continuations if the ancestor task canceled itself or ran into exception.
- don't support (ConcRT) cancellation semantics (the two functions you were referring to, are about this semantic).
- don't support cancel / terminate a already started task by other threads in force.
Basically, with features 1-3, complete cooperative task cancellation semantic is supported.
We will not support item 4 because ConcRT is not portable, and nobody will use it with pplx.
We cannot support item 5 because it's not safe to terminate a thread by force.
So, in general, if someone wants to make his task chain supports cancellation, he would do following :
here is how he would create tasks chain
- create tasks with cancellation_token supplied.
- in long running task functors, capture cancellation token, and call cancellation_token::is_canceled() periodically during long running computation. If it detects cancellation, just call "cancel_current_task()" after releasing all using recourses.
Here is how he would cancel the chain
invoke the cancellation_token_source::cancel() to trigger the cancellation.
If there is anything unclear to you or you have other cancellation semantics need to support, please let us know.
Thank you for your response and explanation. I was working from the task cancellation documentation on MSDN and hence was checking for cancellation request using pplx::is_task_cancellation_requested(), not cancellation_token::is_canceled().
The token-based cooperative cancellation model (1-3) is exactly what I want, the issue was simply that I thought part of it had not been implemented. I switched over to testing for cancellation_token::is_canceled() and everything works well. I guess it would
be slightly nicer not to have to capture the token in the functor, but is no big deal.