Flutter任务取消管理插件cancellation_token的使用
Flutter任务取消管理插件cancellation_token的使用
Dart Cancellation Token
Dart Cancellation Token 是一个用于轻松实现异步任务取消的工具包。它可以帮助开发者在Flutter应用中取消Futures并清理资源(例如关闭HttpClient),当Widget被销毁时,或者复用单个CancellationToken来取消多个任务。
功能特性
- 取消Futures和清理资源:当Flutter中的Widget被销毁时,可以取消所有使用该Token的任务。
- 复用CancellationToken:可以通过调用
.cancel()
方法一次性取消多个任务。 - 取消Isolates:通过
cancellableCompute
取消Isolate。 - 创建自定义可取消对象:使用Cancellable mixin创建自己的可取消逻辑。
Cancellation Tokens 类型
CancellationToken
标准的CancellationToken用于手动取消任务。调用.cancel()
后,所有使用此令牌的任务都会被取消,默认情况下会抛出CancelledException
异常,也可以传递自定义异常。
TimeoutCancellationToken
用于在特定时间后取消任务。默认情况下,超时时会抛出TimeoutException
异常,可通过timeoutException
参数设置自定义异常。使用lazyStart
参数控制计时器是否立即开始。
MergedCancellationToken
合并多个CancellationToken。创建时可以使用构造函数或现有Token上的.merge()
方法。注意,合并后的取消异常不一定来自最先取消的那个Token。
使用示例
以下是一个完整的Flutter Demo应用程序,演示了如何使用Cancellation Token进行任务管理和取消:
import 'package:cancellation_token/cancellation_token.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Cancellation Token Demo',
home: DemoPage(),
);
}
}
class DemoPage extends StatefulWidget {
@override
_DemoPageState createState() => _DemoPageState();
}
class _DemoPageState extends State<DemoPage> {
final Map<String, String> _taskStatus = {
'Delayed Future': 'Stopped',
'Simultaneous A': 'Stopped',
'Simultaneous B': 'Stopped',
'Simultaneous C': 'Stopped',
'Isolate': 'Stopped',
};
CancellationToken? _cancellationToken;
Future<void> _startTasks() async {
// 取消当前运行的任务并创建新的CancellationToken
_cancellationToken?.cancel();
_cancellationToken = CancellationToken();
// 重置任务状态
setState(() => _taskStatus.updateAll((key, value) => 'Stopped'));
try {
// 启动延迟Future
setState(() => _taskStatus['Delayed Future'] = 'Running');
await delayedFuture().asCancellable(_cancellationToken);
setState(() => _taskStatus['Delayed Future'] = 'Complete');
// 并行启动多个延迟Future
setState(() {
_taskStatus['Simultaneous A'] = 'Running';
_taskStatus['Simultaneous B'] = 'Running';
_taskStatus['Simultaneous C'] = 'Running';
});
await Future.wait([
delayedFuture().asCancellable(_cancellationToken).then((_) =>
setState(() => _taskStatus['Simultaneous A'] = 'Complete')),
delayedFuture().asCancellable(_cancellationToken).then((_) =>
setState(() => _taskStatus['Simultaneous B'] = 'Complete')),
delayedFuture().asCancellable(_cancellationToken).then((_) =>
setState(() => _taskStatus['Simultaneous C'] = 'Complete')),
]);
// 在隔离区中执行任务
setState(() => _taskStatus['Isolate'] = 'Running');
await CancellableIsolate.run(
() => delayedIsolateFunction(Duration(seconds: 2)),
_cancellationToken,
);
setState(() => _taskStatus['Isolate'] = 'Complete');
} on CancelledException {
// 忽略取消异常
} catch (e) {
// 处理其他异常
}
}
@override
void dispose() {
_cancellationToken?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Cancellation Token Demo')),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
..._taskStatus.entries.map((entry) => ListTile(
title: Text('${entry.key} status'),
subtitle: Text(entry.value),
)),
SizedBox(height: 16.0),
ElevatedButton(
onPressed: _startTasks,
child: Text('Run Tasks'),
),
ElevatedButton(
onPressed: () => _cancellationToken?.cancel(),
child: Text('Cancel Running Tasks'),
),
],
),
),
);
}
}
/// 模拟延迟操作
Future<void> delayedFuture() async {
await Future.delayed(Duration(seconds: Random().nextInt(5) + 1));
}
/// 模拟隔离区任务
void delayedIsolateFunction(Duration delay) {
print('Isolate started - Waiting ${delay.inSeconds} seconds');
sleep(delay);
print('Isolate finished');
}
这个例子展示了如何使用cancellation_token
库来管理Flutter应用中的异步任务,并提供了取消这些任务的能力。你可以根据需要调整和扩展代码以适应具体的应用场景。
更多关于Flutter任务取消管理插件cancellation_token的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter任务取消管理插件cancellation_token的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter中使用cancellation_token
插件进行任务取消管理的示例代码。这个插件允许你在执行长时间运行的任务时,能够优雅地取消这些任务。
首先,确保你已经在pubspec.yaml
文件中添加了cancellation_token
依赖:
dependencies:
flutter:
sdk: flutter
cancellation_token: ^x.y.z # 请替换为最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,我们来看一个完整的示例,展示如何使用cancellation_token
来管理任务的取消。
示例代码
import 'package:flutter/material.dart';
import 'package:cancellation_token/cancellation_token.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Cancellation Token Example'),
),
body: Center(
child: CancellationTokenExample(),
),
),
);
}
}
class CancellationTokenExample extends StatefulWidget {
@override
_CancellationTokenExampleState createState() => _CancellationTokenExampleState();
}
class _CancellationTokenExampleState extends State<CancellationTokenExample> {
CancellationTokenSource? _cancellationTokenSource;
void _startLongRunningTask() {
// 创建一个新的CancellationTokenSource
_cancellationTokenSource = CancellationTokenSource();
final CancellationToken token = _cancellationTokenSource!.token;
// 模拟一个长时间运行的任务
Future.delayed(Duration(seconds: 10), () {
if (!token.isCancellationRequested) {
// 如果任务没有被取消,则更新UI
setState(() {
// 例如,显示任务完成的信息
});
}
});
// 在另一个线程中定期检查取消请求
_checkCancellation(token);
}
void _checkCancellation(CancellationToken token) async {
while (true) {
await Future.delayed(Duration(milliseconds: 100)); // 每100毫秒检查一次
if (token.isCancellationRequested) {
print('Task was cancelled.');
// 可以在这里执行清理操作
break;
}
}
}
void _cancelTask() {
_cancellationTokenSource?.requestCancellation();
_cancellationTokenSource = null; // 重置源,以便可以开始新任务
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: _startLongRunningTask,
child: Text('Start Long Running Task'),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: _cancelTask,
child: Text('Cancel Task'),
),
],
);
}
}
解释
- 依赖添加:在
pubspec.yaml
中添加cancellation_token
依赖。 - 创建
CancellationTokenSource
:在_startLongRunningTask
方法中,创建一个新的CancellationTokenSource
实例,并获取其token
。 - 模拟长时间任务:使用
Future.delayed
模拟一个长时间运行的任务。在这个例子中,任务将在10秒后完成,但如果在任务完成前请求取消,它将不会更新UI。 - 定期检查取消请求:在
_checkCancellation
方法中,使用一个无限循环每100毫秒检查一次是否请求了取消。如果请求了取消,则打印一条消息并退出循环。 - 请求取消:在
_cancelTask
方法中,调用_cancellationTokenSource?.requestCancellation()
来请求取消任务,并将_cancellationTokenSource
重置为null
,以便可以开始新任务。
这个示例展示了如何使用cancellation_token
插件来管理Flutter中的任务取消。你可以根据实际需求对代码进行修改和扩展。