Skip to content

Dart Cancellation Token. Inspired by CancellationToken in C#. A Dart utility package for easy async task cancellation.

License

Notifications You must be signed in to change notification settings

hoc081098/cancellation_token_hoc081098

Repository files navigation

cancellation_token_hoc081098

Dart CI Pub Pub codecov GitHub Style Hits

Dart Cancellation Token. Inspired by CancellationToken in C#. A Dart utility package for easy async task cancellation.

Features

  • Reuse a single CancellationToken for multiple tasks, and cancel all of them with a single call to CancellationToken.cancel().
  • Cancel futures and clean-up resources with token.guardFuture(block).
  • Cancel streams and clean-up resources with token.guardStream(stream)/Stream.guardedBy(token).
  • Integrate with rxdart/rxdart_ext with useCancellationToken.
  • Very simple, lightweight, performant, and easy to use.

Getting started

1. Add dependency

dependencies:
  cancellation_token_hoc081098: <latest_version>

2. Import

import 'package:cancellation_token_hoc081098/cancellation_token_hoc081098.dart';

Usage

1. guardFuture

void main() async {
  // Create a CancellationToken
  final token = CancellationToken();

  // Simulate a long-running task
  Future<void> doWork(int number) async {
    print('doWork($number) started');
    await Future<void>.delayed(const Duration(milliseconds: 100));
    print('doWork($number) finished');
  }

  // Guard a Future
  final future = token.guardFuture(() async {
    for (var i = 0; i < 10; i++) {
      token.guard(); // Throws if token is cancelled
      await doWork(i);
      token.guard(); // Throws if token is cancelled
    }
    return 42;
  });

  future
      .then((v) => print('Result: $v'))
      .onError<Object>((e, st) => print('Error: $e'));

  // Cancel the token after 300ms
  await Future<void>.delayed(const Duration(milliseconds: 300));

  // Cancel the token
  token.cancel();

  // Wait a little longer to ensure that the Future is cancelled
  await Future<void>.delayed(const Duration(seconds: 2));

  // Output:
  // doWork(0) started
  // doWork(0) finished
  // doWork(1) started
  // doWork(1) finished
  // doWork(2) started
  // Error: CancellationException
  // doWork(2) finished
}

2. guardStream

void main() async {
  // Create a CancellationToken
  final token = CancellationToken();

  // Simulate a long-running task
  Future<void> doWork(int number) async {
    print('doWork($number) started');
    await Future<void>.delayed(const Duration(milliseconds: 100));
    print('doWork($number) finished');
  }

  // Guard a Stream
  final stream = Rx.fromCallable(() async {
    for (var i = 0; i < 10; i++) {
      token.guard(); // Throws if token is cancelled
      await doWork(i);
      token.guard(); // Throws if token is cancelled
    }
    return 42;
  }).guardedBy(token);

  stream
      .doOnData((v) => print('Result: $v'))
      .doOnError((e, st) => print('Error: $e'))
      .listen(null);

  // Cancel the token after 300ms
  await Future<void>.delayed(const Duration(milliseconds: 300));

  // Cancel the token
  token.cancel();

  // Wait a little longer to ensure that the stream is cancelled
  await Future<void>.delayed(const Duration(seconds: 2));

  // Output:
  // doWork(0) started
  // doWork(0) finished
  // doWork(1) started
  // doWork(1) finished
  // doWork(2) started
  // Error: CancellationException
  // doWork(2) finished
}

3. useCancellationToken

import 'package:rxdart_ext/rxdart_ext.dart';

void main() async {
  // Simulate a long-running task
  Future<void> doWork(int number) async {
    print('doWork($number) started');
    await Future<void>.delayed(const Duration(milliseconds: 100));
    print('doWork($number) finished');
  }

  // useCancellationToken
  final Single<int> single = useCancellationToken((cancelToken) async {
    for (var i = 0; i < 10; i++) {
      cancelToken.guard(); // Throws if token is cancelled
      await doWork(i);
      cancelToken.guard(); // Throws if token is cancelled
    }
    return 42;
  });

  final subscription = single
      .doOnData((v) => print('Result: $v'))
      .doOnError((e, st) => print('Error: $e'))
      .listen(null);

  // Cancel the subscription after 300ms
  await Future<void>.delayed(const Duration(milliseconds: 300));

  // Cancel the subscription
  await subscription.cancel();

  // Wait a little longer to ensure that the stream is cancelled
  await Future<void>.delayed(const Duration(seconds: 2));

  // Output:
  // doWork(0) started
  // doWork(0) finished
  // doWork(1) started
  // doWork(1) finished
  // doWork(2) started
  // doWork(2) finished
}

Features and bugs

Please file feature requests and bugs at the issue tracker.

License

MIT License

Copyright (c) 2022 Petrus Nguyễn Thái Học

About

Dart Cancellation Token. Inspired by CancellationToken in C#. A Dart utility package for easy async task cancellation.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages