RequestCancellation Request Cancellation Cancel Execution of Taskflows RequestCancellation_1CancelARunningTaskflow Understand the Limitations of Cancellation RequestCancellation_1UnderstandTheLimitationsOfCancellation This chapters discusses how to cancel submitted tasks. Cancel Execution of Taskflows When you submit a taskflow to an executor (e.g., tf::Executor::run), the executor returns a tf::Future object that will hold the result of the execution. tf::Future is a derived class from std::future. In addition to base methods of std::future, you can call tf::Future::cancel to cancel the execution of a running taskflow. The following example cancels a submission of a taskflow that contains 1000 tasks each running one second. tf::Executorexecutor; tf::Taskflowtaskflow; for(inti=0;i<1000;i++){ taskflow.emplace([](){ std::this_thread::sleep_for(std::chrono::seconds(1)); }); } //submitthetaskflow tf::Future<void>fu=executor.run(taskflow); //requesttocanceltheabovesubmittedexecution fu.cancel(); //waituntilthecancellationcompletes fu.get(); tf::Future::cancel is non-deterministic and out-of-order. When you request a cancellation, the executor will stop scheduling the rest tasks of the taskflow. Tasks that are already running will continue to finish, but their successor tasks will not be scheduled to run. A cancellation is considered complete when all these running tasks finish. To wait for a cancellation to complete, you may explicitly call tf::Future::get. It is your responsibility to ensure that the taskflow remains alive before the cancellation completes. For instance, the following code results in undefined behavior: tf::Executorexecutor; { tf::Taskflowtaskflow; for(inti=0;i<1000;i++){ taskflow.emplace([](){}); } tf::Futurefu=executor.run(taskflow); fu.cancel();//therecanstillbetaskrunningaftercancellation }//destroyingtaskflowherecanresultinundefinedbehavior The undefined behavior problem exists because tf::Future::cancel does not guarantee an immediate cancellation. To fix the problem, call get to ensure the cancellation completes before the end of the scope destroys the taskflow. tf::Executorexecutor; { tf::Taskflowtaskflow; for(inti=0;i<1000;i++){ taskflow.emplace([](){}); } tf::Futurefu=executor.run(taskflow); fu.cancel();//therecanstillbetaskrunningaftercancellation fu.get();//waitsuntilthecancellationcompletes } Understand the Limitations of Cancellation Canceling the execution of a running taskflow has the following limitations: Cancellation is non-preemptive. A running task will not be cancelled until it finishes. Cancelling a taskflow with tasks acquiring and/or releasing tf::Semaphore results is currently not supported. We may overcome these limitations in the future releases.