cancellation_token 1.3.1 copy "cancellation_token: ^1.3.1" to clipboard
cancellation_token: ^1.3.1 copied to clipboard

outdated

Easy async task cancellation for tasks using cancellation tokens in Dart.

Dart Cancellation Token #

A Dart utility package for easy async task cancellation.

For Dart versions below 2.15.0, use version 1.0.0 of this package.

Features #

  • Cancel futures and clean-up resources (e.g. closing an HttpClient) when a widget is disposed in Flutter
  • Reuse a single CancellationToken for multiple tasks, and cancel them all with a single call to .cancel()
  • Cancel isolates with cancellableCompute
  • Create your own cancellables that use CancellationTokens with the Cancellable mixin

Cancellation Tokens #

CancellationToken #

The standard CancellationToken can be used to manually cancel tasks. When .cancel() is called, all cancellables using the token will be cancelled. By default, async tasks cancelled with a CancellationToken will throw a CancelledException. You can pass a custom exception using .cancel(CustomException()) to change this.

TimeoutCancellationToken #

To cancel tasks after a certain amount of time, you can use a TimeoutCancellationToken in place of the standard CancellationToken. By default, async tasks will be cancelled with a TimeoutException when the timeout duration ends. You can pass a custom exception by using the timeoutException parameter.

When a TimeoutCancellationToken is created, the timer will begin immediately. To only start the timer when the token is attached to a task, set the lazyStart parameter to true.

Usage #

Cancelling Futures #

To make an existing future cancellable, you can use the .asCancellable() extension.

CancellationToken cancellationToken = CancellationToken();

@override
void initState() {
  super.initState();
  loadData();
}

@override
void dispose() {
  // All futures using this token will be cancelled when this widget is disposed
  cancellationToken.cancel();
  super.dispose();
}

Future<void> loadData() async {
  try {
    // The CancellationToken can be used for multiple tasks
    someDataA = await getDataA().asCancellable(cancellationToken);
    someDataB = await getDataB().asCancellable(cancellationToken);
    setState(() {
      // ...
    });
  } on CancelledException {
    // Ignore cancellations
  } catch (e, stackTrace) {
    setState(() => error = true);
  }
}

Cancellable Completer #

The CancellableCompleter class can be used in place of a standard Completer to make it cancellable. This completer implements the base Completer class, so it works as a drop-in replacement.

CancellableCompleter<String> completer = CancellableCompleter<String>(
  cancellationtoken, 
  onCancel: () {
    // The optional onCancel callback can be used to clean up resources when the 
    // token is cancelled
  }
);

// Complete with either the result or an error as usual, these will only have an 
// effect if the completer hasn't already been cancelled
completer.complete(result);
complete.completeError(e, stackTrace);

// This future will complete with the result or the cancellation exception, 
// whichever is first
return completer.future;

Cancellable Isolates #

If you need to run an intensive synchronous task, like parsing a large JSON API response, you can use an isolate to avoid blocking the UI thread. With the cancellableCompute() function, you can run a static or top level function in an isolate and kill the isolate early using a CancellationToken. This function is based on Flutter's compute() method.

When cancellableCompute is cancelled, the isolate will be killed immediately to free up device resources. If your callback function performs I/O operations such as file writes, these may not complete.

Isolates aren't supported when building for web. As a fallback, cancellableCompute will return a future that completes with either the cancellation exception or the result of the callback, depending on whether or not the CancellationToken was already cancelled when it was called.

final ChunkyApiResponse response = await cancellableCompute(
  _readAndParseJson,
  jsonString,
  cancellationToken
);

static ChunkyApiResponse _readAndParseJson(String json) {
  final Map<String, dynamic> decodedJson = jsonDecode(json);
  return ChunkyApiResponse.fromJson(decodedJson);
}

Custom Cancellables #

The Cancellable mixin can be used to make your own cancellables. This might be useful for custom I/O libraries, like a custom HTTP library.

  • DO detach from the CancellationToken when your async task completes.
  • DON'T attach to a CancellationToken that has already been cancelled, instead use the maybeAttach method to check if it's already been cancelled and only start your async task if it returns `false.
  • DON'T cancel the CancellationToken within a Cancellable, as it may be used for other tasks.
class MyCancellable with Cancellable {
  MyCancellable(this.cancellationToken) {
    // Call `maybeAttach()` to only attach if the cancellation token hasn't 
    // already been cancelled
    if (maybeAttach(this.cancellationToken)) {
      // Start your async task here
    }
  }

  final CancellationToken cancellationToken;

  /// Override `onCancel()` to clean up resources after cancellation.
  @override
  void onCancel(Exception cancelException) {
    // Clean up resources here, like closing an HttpClient
  }
  
  void complete() {
    // If your async task completes before the token is cancelled, 
    // detatch from the token
    _cancellationToken.detach(this);
  }
}

19
likes
0
pub points
90%
popularity

Publisher

verified publisherjonathancole.dev

Easy async task cancellation for tasks using cancellation tokens in Dart.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

meta

More

Packages that depend on cancellation_token