Flutter取消任务管理插件cancellation_token_hoc081098的使用
Flutter取消任务管理插件 cancellation_token_hoc081098
的使用
简介
cancellation_token_hoc081098
是一个受 C# 中的 CancellationToken
启发的 Dart 实用程序包,旨在简化异步任务的取消和资源清理。
主要功能
- 复用:可以复用单个
CancellationToken
来取消多个任务。 - 取消 Futures 和 Streams:提供
token.guardFuture(block)
和token.guardStream(stream)
方法来取消 Future 和 Stream,并清理资源。 - 与 rxdart 集成:支持通过
useCancellationToken
与 rxdart/rxdart_ext 集成。 - 简单、轻量、高效且易于使用。
使用步骤
1. 添加依赖
在 pubspec.yaml
文件中添加以下依赖:
dependencies:
cancellation_token_hoc081098: <latest_version>
2. 导入包
在 Dart 文件中导入该包:
import 'package:cancellation_token_hoc081098/cancellation_token_hoc081098.dart';
示例代码
1. 使用 guardFuture
void main() async {
// 创建 CancellationToken
final token = CancellationToken();
// 模拟一个长时间运行的任务
Future<void> doWork(int number) async {
print('doWork($number) started');
await Future<void>.delayed(const Duration(milliseconds: 100));
print('doWork($number) finished');
}
// 使用 guardFuture 保护 Future
final future = token.guardFuture(() async {
for (var i = 0; i < 10; i++) {
token.guard(); // 如果 token 被取消则抛出异常
await doWork(i);
token.guard(); // 如果 token 被取消则抛出异常
}
return 42;
});
future
.then((v) => print('Result: $v'))
.onError<Object>((e, st) => print('Error: $e'));
// 在 300ms 后取消 token
await Future<void>.delayed(const Duration(milliseconds: 300));
// 取消 token
token.cancel();
// 等待一段时间以确保 Future 已被取消
await Future<void>.delayed(const Duration(seconds: 2));
// 输出示例:
// 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 {
// 创建 CancellationToken
final token = CancellationToken();
// 模拟一个长时间运行的任务
Future<void> doWork(int number) async {
print('doWork($number) started');
await Future<void>.delayed(const Duration(milliseconds: 100));
print('doWork($number) finished');
}
// 使用 guardStream 保护 Stream
final stream = Rx.fromCallable(() async {
for (var i = 0; i < 10; i++) {
token.guard(); // 如果 token 被取消则抛出异常
await doWork(i);
token.guard(); // 如果 token 被取消则抛出异常
}
return 42;
}).guardedBy(token);
stream
.doOnData((v) => print('Result: $v'))
.doOnError((e, st) => print('Error: $e'))
.listen(null);
// 在 300ms 后取消 token
await Future<void>.delayed(const Duration(milliseconds: 300));
// 取消 token
token.cancel();
// 等待一段时间以确保 Stream 已被取消
await Future<void>.delayed(const Duration(seconds: 2));
// 输出示例:
// 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 {
// 模拟一个长时间运行的任务
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(); // 如果 token 被取消则抛出异常
await doWork(i);
cancelToken.guard(); // 如果 token 被取消则抛出异常
}
return 42;
});
final subscription = single
.doOnData((v) => print('Result: $v'))
.doOnError((e, st) => print('Error: $e'))
.listen(null);
// 在 300ms 后取消订阅
await Future<void>.delayed(const Duration(milliseconds: 300));
// 取消订阅
await subscription.cancel();
// 等待一段时间以确保流已被取消
await Future<void>.delayed(const Duration(seconds: 2));
// 输出示例:
// doWork(0) started
// doWork(0) finished
// doWork(1) started
// doWork(1) finished
// doWork(2) started
// doWork(2) finished
}
完整示例 Demo
以下是完整的示例代码,展示了如何使用 cancellation_token_hoc081098
包的不同功能:
import 'package:cancellation_token_hoc081098/cancellation_token_hoc081098.dart';
import 'package:rxdart_ext/rxdart_ext.dart';
final separator = '-' * 30;
void onError(Object error, StackTrace stackTrace) =>
print('[onError] error: $error, stackTrace: $stackTrace');
void main() async {
print('${separator}guardFutureExample$separator');
await guardFutureExample();
print('${separator}guardStreamExample$separator');
await guardStreamExample();
print('${separator}reuseTokenExample$separator');
await reuseTokenExample();
print('${separator}useCancellationToken$separator');
await useCancellationTokenExample();
await delay(2000);
print('${separator}done$separator');
}
Future<void> guardStreamExample() async {
final token = CancellationToken();
// 可以使用 stream.guardedBy(token) 替代 token.guardStream(stream)
final stream = token.guardStream(Rx.fromCallable(() async {
print('start...');
token.guard();
await delay(100);
token.guard();
print('Step 1');
token.guard();
await delay(100);
token.guard();
print('Step 2');
token.guard();
await delay(100);
token.guard();
print('done...');
return 42;
}));
stream.listen(print, onError: onError);
await delay(120);
token.cancel();
await delay(800);
print('exit...');
}
Future<void> guardFutureExample() async {
final token = CancellationToken();
final future = token.guardFuture((token) async {
print('start...');
token.guard();
await delay(100);
token.guard();
print('Step 1');
token.guard();
await delay(100);
token.guard();
print('Step 2');
token.guard();
await delay(100);
token.guard();
print('done...');
return 42;
});
future.then(print, onError: onError).ignore();
await delay(120);
token.cancel();
await delay(800);
print('exit...');
}
Future<void> reuseTokenExample() async {
final token = CancellationToken();
final future1 = token.guardFuture((token) async {
for (var i = 0; i < 10; i++) {
token.guard();
print('future1: start $i');
await delay(100);
print('future1: end $i');
token.guard();
}
});
final future2 = token.guardFuture((token) async {
for (var i = 0; i < 10; i++) {
token.guard();
print('future2: start $i');
await delay(100);
print('future2: end $i');
token.guard();
}
});
Future.wait([future1, future2])
.then((result) => print('result: $result'), onError: onError)
.ignore();
await delay(250);
token.cancel();
await delay(800);
print('exit...');
}
Future<void> useCancellationTokenExample() async {
final single = useCancellationToken((token) async {
print('start...');
token.guard();
await delay(100);
token.guard();
print('Step 1');
token.guard();
await delay(100);
token.guard();
print('Step 2');
token.guard();
await delay(100);
token.guard();
print('done...');
return 42;
});
final subscription = single.listen(print, onError: onError);
await delay(120);
await subscription.cancel();
await delay(800);
print('exit...');
}
Future<void> delay(int milliseconds) => Future<void>.delayed(Duration(milliseconds: milliseconds));
更多关于Flutter取消任务管理插件cancellation_token_hoc081098的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
1 回复
更多关于Flutter取消任务管理插件cancellation_token_hoc081098的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter中使用cancellation_token_hoc081098
插件进行任务取消管理的代码示例。这个插件允许你在异步任务执行过程中,通过令牌(token)来取消任务。
首先,确保你已经在pubspec.yaml
文件中添加了依赖项:
dependencies:
flutter:
sdk: flutter
cancellation_token_hoc081098: ^latest_version # 请使用最新版本号
然后运行flutter pub get
来获取依赖。
接下来是一个完整的代码示例,展示如何使用这个插件来取消一个异步任务:
import 'package:flutter/material.dart';
import 'package:cancellation_token_hoc081098/cancellation_token.dart';
import 'dart:async';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final CancellationTokenSource _cancellationTokenSource = CancellationTokenSource();
bool _isRunning = false;
String _result = '';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Cancellation Token Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
_result,
style: TextStyle(fontSize: 20),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: _isRunning ? null : _startTask,
child: Text(_isRunning ? 'Running...' : 'Start Task'),
),
SizedBox(height: 10),
ElevatedButton(
onPressed: _isRunning ? _cancelTask : null,
child: Text(_isRunning ? 'Cancel Task' : ''),
),
],
),
),
);
}
void _startTask() {
setState(() {
_isRunning = true;
_result = '';
});
_performAsyncTask(_cancellationTokenSource.token).then((result) {
setState(() {
_isRunning = false;
_result = 'Task Result: $result';
});
}).catchError((error) {
if (error is CancellationTokenError) {
setState(() {
_isRunning = false;
_result = 'Task Cancelled';
});
} else {
setState(() {
_isRunning = false;
_result = 'Task Error: $error';
});
}
});
}
Future<int> _performAsyncTask(CancellationToken token) async {
for (int i = 0; i <= 10; i++) {
// Check if the token has been cancelled
if (token.isCancelled) {
throw CancellationTokenError();
}
// Simulate async work with a delay
await Future.delayed(Duration(seconds: 1));
print('Task Progress: $i');
}
return 10;
}
void _cancelTask() {
_cancellationTokenSource.cancel();
}
}
// Custom error to indicate task cancellation
class CancellationTokenError implements Exception {}
代码解释:
- 依赖项:在
pubspec.yaml
中添加cancellation_token_hoc081098
依赖项。 - 状态管理:在
_MyHomePageState
中,我们使用_isRunning
来跟踪任务是否正在运行,_result
来显示结果。 - CancellationTokenSource:创建一个
CancellationTokenSource
实例,用于生成和管理取消令牌。 - 启动任务:
_startTask
方法启动异步任务,并将取消令牌传递给任务函数。 - 异步任务:
_performAsyncTask
方法模拟一个异步任务,每秒钟检查一次令牌是否被取消。 - 取消任务:
_cancelTask
方法调用_cancellationTokenSource.cancel()
来取消任务。 - 错误处理:在任务完成时,检查是否有
CancellationTokenError
来更新UI,显示任务被取消。
这个示例展示了如何使用cancellation_token_hoc081098
插件在Flutter中进行任务取消管理。希望这对你有所帮助!