# Cookbook » Request Cancellation

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::Executor executor;
    tf::Taskflow taskflow;

    for(int i=0; i<1000; i++) {
      taskflow.emplace([](){
        std::this_thread::sleep_for(std::chrono::seconds(1));
      });
    }

    // submit the taskflow
    tf::Future fu = executor.run(taskflow);

    // request to cancel the above submitted execution
    fu.cancel();

    // wait until the cancellation completes
    fu.get();

#### Note

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`.

#### Attention

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::Executor executor;
    {
      tf::Taskflow taskflow;

      for(int i=0; i<1000; i++) {
        taskflow.emplace([](){});
      }

      tf::Future fu = executor.run(taskflow);

      fu.cancel();  // there can still be task running after cancellation

    } // destroying taskflow here can result in undefined behavior

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::Executor executor;
    {
      tf::Taskflow taskflow;

      for(int i=0; i<1000; i++) {
        taskflow.emplace([](){});
      }

      tf::Future fu = executor.run(taskflow);

      fu.cancel();  // there can still be task running after cancellation
      fu.get();     // waits until the cancellation completes
    }

## 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.

Tab / T to search, Esc to close
…

Search for symbols, directories, files, pages or modules. You can omit any prefix from the symbol or file path; adding a `:` or `/` suffix lists all members of given symbol or directory.

Use ↓ / ↑ to navigate through the list, Enter to go. Tab autocompletes common prefix, you can copy a link to the result using ⌘ L while ⌘ M produces a Markdown link.

Sorry, nothing was found.