Flutter取消任务管理插件cancellation_token_dotnet的使用

Flutter取消任务管理插件cancellation_token_dotnet的使用

在Flutter开发中,我们经常需要处理长时间运行的任务,并且希望能够在需要时取消这些任务。cancellation_token_dotnet 插件提供了类似于 .NET 中 CancellationToken 的功能,使我们在Dart语言中能够更方便地进行任务取消操作。

安装插件

首先,在你的pubspec.yaml文件中添加该插件:

dependencies:
  cancellation_token_dotnet: ^最新版本号

然后运行flutter pub get以安装插件。

使用示例

下面是一个完整的示例代码,展示了如何使用cancellation_token_dotnet插件来管理任务的取消。

import 'package:flutter/material.dart';
import 'package:cancellation_token_dotnet/cancellation_token_dotnet.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('取消任务管理示例')),
        body: Center(
          child: RaisedButton(
            onPressed: () {
              // 创建一个CancellationTokenSource对象
              CancellationTokenSource cts = CancellationTokenSource()
                ..cancelAfter(const Duration(milliseconds: 4000));

              // 启动四个长运行任务
              Future<String> t1 = aLongRunningTask(
                const Duration(milliseconds: 250),
                "t1",
                token: cts.token,
              );
              Future<String> t2 = aLongRunningTask(
                const Duration(milliseconds: 500),
                "t2",
                token: cts.token,
              );
              Future<String> t3 = aLongRunningTask(
                const Duration(milliseconds: 750),
                "t3",
                token: cts.token,
              );
              Future<String> t4 = aLongRunningTask(
                const Duration(milliseconds: 1000),
                "t4",
                token: cts.token,
              );

              // 注册一个回调函数
              CancellationTokenRegistration ctr = cts.register(
                callback: (Object? state, CancellationToken token) {
                  print("Callback has run");
                },
                state: Object(),
              );

              // 等待所有任务完成
              try {
                await Future.wait<String>([t1, t2, t3, t4]);
              } on OperationCancelledException catch (e, st) {
                print("Operation is cancelled. Exception $e, Stack Trace: $st");
              }
            },
            child: Text('启动任务'),
          ),
        ),
      ),
    );
  }
}

// 模拟一个长时间运行的任务
Future<String> aLongRunningTask(Duration duration, String taskName, {CancellationToken token = CancellationToken.none}) async {
  print("Running Task name: $taskName");
  int iteration = 1;
  while (!token.isCancellationRequested) {
    print("Task name: $taskName, iteration: $iteration");
    await Future<void>.delayed(duration);
    ++iteration;
  }

  if (taskName == "t4") {
    token.throwIfCancellationRequested();
  }

  print("Completed Task name: $taskName");

  return taskName;
}

代码解释

  1. 创建CancellationTokenSource对象

    CancellationTokenSource cts = CancellationTokenSource()
      ..cancelAfter(const Duration(milliseconds: 4000));
    

    这里我们创建了一个CancellationTokenSource对象,并设置了一个4秒的超时时间。

  2. 启动多个长运行任务

    Future<String> t1 = aLongRunningTask(
      const Duration(milliseconds: 250),
      "t1",
      token: cts.token,
    );
    Future<String> t2 = aLongRunningTask(
      const Duration(milliseconds: 500),
      "t2",
      token: cts.token,
    );
    Future<String> t3 = aLongRunningTask(
      const Duration(milliseconds: 750),
      "t3",
      token: cts.token,
    );
    Future<String> t4 = aLongRunningTask(
      const Duration(milliseconds: 1000),
      "t4",
      token: cts.token,
    );
    

    我们启动了四个不同的长运行任务,每个任务都有自己的执行间隔时间。

  3. 注册回调函数

    CancellationTokenRegistration ctr = cts.register(
      callback: (Object? state, CancellationToken token) {
        print("Callback has run");
      },
      state: Object(),
    );
    

    我们注册了一个回调函数,当任务被取消时会触发。

  4. 等待任务完成

    try {
      await Future.wait<String>([t1, t2, t3, t4]);
    } on OperationCancelledException catch (e, st) {
      print("Operation is cancelled. Exception $e, Stack Trace: $st");
    }
    

更多关于Flutter取消任务管理插件cancellation_token_dotnet的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter取消任务管理插件cancellation_token_dotnet的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用cancellation_token_dotnet插件来管理任务取消的示例代码。请注意,cancellation_token_dotnet这个名称听起来更像是为.NET平台设计的,但在Flutter中,我们通常使用Dart语言及其生态系统来实现类似的功能。Flutter本身并没有直接名为cancellation_token_dotnet的插件,但我们可以使用Dart中的FutureCompleter来实现任务取消的功能。

不过,为了贴近你的要求,并假设存在一个类似于.NET CancellationToken的Flutter插件(虽然实际上没有直接对应的插件),我会展示一个基于Dart原生的解决方案,这可以很容易地适应任何类似插件的API。

使用Dart的FutureCompleter实现任务取消

首先,我们需要定义一个简单的任务管理器和取消令牌。虽然这不是一个插件,但它展示了如何在Dart中实现类似的功能。

import 'dart:async';

class CancellationToken {
  bool isCancellationRequested = false;

  void requestCancellation() {
    isCancellationRequested = true;
  }
}

class TaskManager {
  Future<void> performTask(CancellationToken token, Function taskFunction) async {
    Completer<void> completer = Completer<void>();

    // Simulate a long-running task
    Future.delayed(Duration(seconds: 10), () async {
      if (token.isCancellationRequested) {
        completer.completeError(CanceledError("Task was canceled"));
      } else {
        try {
          await taskFunction();
          completer.complete();
        } catch (e) {
          completer.completeError(e);
        }
      }
    });

    return completer.future;
  }
}

class CanceledError implements Exception {
  String message;
  CanceledError(this.message);
}

void main() async {
  CancellationToken token = CancellationToken();
  TaskManager taskManager = TaskManager();

  Future<void> longRunningTask() async {
    // Simulate work being done
    for (int i = 0; i < 10; i++) {
      if (token.isCancellationRequested) {
        throw CanceledError("Task was canceled during iteration $i");
      }
      await Future.delayed(Duration(seconds: 1));
      print("Task progress: $i");
    }
    print("Task completed");
  }

  Future<void> taskFuture = taskManager.performTask(token, longRunningTask);

  // Cancel the task after 3 seconds
  Future.delayed(Duration(seconds: 3), () {
    token.requestCancellation();
    print("Cancellation requested");
  });

  try {
    await taskFuture;
    print("Task executed successfully");
  } catch (e) {
    if (e is CanceledError) {
      print(e.message);
    } else {
      print("An unexpected error occurred: $e");
    }
  }
}

解释

  1. CancellationToken 类:

    • 包含一个布尔值isCancellationRequested,用于指示是否已请求取消。
    • 提供requestCancellation方法,用于设置isCancellationRequestedtrue
  2. TaskManager 类:

    • 包含一个方法performTask,该方法接受一个CancellationToken和一个任务函数作为参数。
    • 使用Completer<void>来创建一个Future,该Future将在任务完成时或取消时被解析。
    • 使用Future.delayed模拟一个长时间运行的任务。
  3. longRunningTask 函数:

    • 模拟一个执行10次迭代的任务,每次迭代之间延迟1秒。
    • 如果在迭代过程中请求了取消,则抛出CanceledError
  4. main 函数:

    • 创建一个CancellationToken实例和一个TaskManager实例。
    • 定义一个longRunningTask函数并将其传递给taskManager.performTask
    • 使用Future.delayed在3秒后请求取消任务。
    • 等待任务完成或捕获取消错误。

这个示例展示了如何在Dart中管理任务取消,尽管它并不是直接使用任何名为cancellation_token_dotnet的插件。如果你有一个特定的Flutter插件用于此目的,你可以根据该插件的API调整上述代码。

回到顶部