cancellation_token_hoc081098
Author: Petrus Nguyễn Thái Học
Dart Cancellation Token. Inspired by CancellationToken in C#. A Dart utility package for easy async task cancellation.
Features
x
Reuse a singleCancellationToken
for multiple tasks, and cancel all of them with a single call toCancellationToken.cancel()
.x
Cancel futures and clean-up resources withtoken.guardFuture(block)
.x
Cancel streams and clean-up resources withtoken.guardStream(stream)
/Stream.guardedBy(token)
.x
Integrate with rxdart/rxdart_ext withuseCancellationToken
.x
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