待完成

news/2025/1/3 7:58:52/文章来源:https://www.cnblogs.com/feng88/p/18645230

简介

协程 执行前、执行中、执行后 全部都可以被完美正确的取消;

  • 执行前取消 这个好理解;
  • 执行中,是协程内核 尝试取消;若开发者内部是大耗时协程,开发者自己也可以 通过 IsCancel 判断来结束协程;
  • 执行后,但是有可能衍生出来了很多子协程,这些子协程又是有 前、中、后 3个状态;子协程会连带取消;

协程的取消 通常是不需要开发者关注的,开发者正常取消就可;若你非要写出 大耗时的协程,可以参见 本文扩展部分;

取消回调有2种写法

  1. task.bg(bgBig).onCancelUi(doCanceled).start; 创建协程时,就指定取消回调;

    然后 真正取消的时候,只需要调用 tasks.cancel() 就可;

  2. tasks.cancelWithOnUi(taskId, doCanceled);真正取消的时候,动态指定取消回调;

示例代码

unit main;interfaceusesWinapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ComCtrls, Vcl.StdCtrls, doroutine, System.Generics.Collections;typeTForm3 = class(TForm)Button1: TButton;Button2: TButton;procedure Button1Click(Sender: TObject);procedure Button2Click(Sender: TObject);private{ Private declarations }public{ Public declarations }end;varForm3: TForm3;n: Integer;implementation{$R *.dfm}procedure doCanceled(task: TTask);
beginif TThread.Current.ThreadID = MainThreadID thenbeginShowMessage('主线程 执行了 取消回调');end else beginShowMessage('bg线程 执行了 取消回调');end;
end;procedure bgSmall(task: TTask);
begin//doSomeThing http 请求了,或其他 后台业务Sleep(100); //模拟做事//可看下日志OutputDebugString(PChar(Format('干完了第: %d 个,后,由于被取消了,剩下的不干了!', [AtomicIncrement(n)])));
end;procedure bgBig(task: TTask);
begin//此大协程开启300个bg小协程做事for var i := 1 to 300 dobegintask.bg(bgSmall).start;end;
end;procedure TForm3.Button1Click(Sender: TObject);
beginn := 0; //初始化干了第几个后被取消;//开启一个大协程做事,做的过程中,取消此大协程var tid := task.bg(bgBig).onCancelUi(doCanceled).start; //写法1 创建时候,就指定了取消回调Sleep(1000); //模拟让当前线程睡一会,让后台【线程们】执行一会,然后开始取消// tid := '123'; //可以模拟取消失败;if not tasks.cancel(tid) thenbegin//取消失败,你可以 doSomeThing 做一些事ShowMessage('取消失败');end; // else 取消成功,就会执行 取消成功的回调函数,你这里不需要写什么了,要在取消回调函数里写;
end;procedure TForm3.Button2Click(Sender: TObject);
beginn := 0; //初始化干了第几个后被取消;var tid := task.bg(bgBig).start;Sleep(1000); //模拟让当前线程睡一会,让后台【线程们】执行一会,然后开始取消if not tasks.cancelWithOnUi(tid, doCanceled) then //写法2,创建协程时,不指定取消回调,而是取消时动态指定begin//取消失败,你可以 doSomeThing 做一些事ShowMessage('取消失败');end;
end;end.

效果图

image

扩展

若开发者在一个协程内部出现耗时的循环操作,这样会影响取消的响应速度哦,当然若你这个协程,没有取消的需求,你可以不关注这里;这里并不是那么重要,你即使出现下面这样耗时的 forloop 循环协程,也无伤大雅,只是一个小细节,举例:

procedure forLoopBg(task: TTask);
begin//此大协程开启300个bg小协程做事for var i := 1 to 300 dobeginSleep(1000); //模拟耗时做一些事,外层是一个 for 循环task.bg(bgSmall).start;end;
end;

可见 这个 forLoopBg 协程,是一个非常耗时的协程,长时间不会退出,若你要取消它,协程内核首先会尝试取消它,并释放栈内存;开发者也可以自己通过 isCancel来自我取消,如以下 2 种 解决方案:

  1. 把这个耗时的 forloop 循环协程,拆分成多个小协程;这个其实是 运行效率最高的,协程是并行的;

  2. 在循环内部使用 isCancel 判断下,若为 true 则退出循环,比如修改成 下面这样:

    procedure forLoopBg(task: TTask);
    begin//此大协程开启300个bg小协程做事for var i := 1 to 300 dobeginif task.isCancel thenbeginExit; //或 Break 跳出循环;end;Sleep(1000); //模拟耗时做一些事,外层是一个 for 循环task.bg(bgSmall).start;end;
    end;
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/862180.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Hello World from RVMaker!

RVMaker 的全称是 RISC-V Maker,一个专注于 RISC-V MCU 生态的平台。欢迎关注 RVMaker(RISC-V Maker),一个专注于 RISC-V MCU 生态的平台。 这里分享最新的 RISC-V MCU 开发教程、技术文章与应用方案,帮助开发者深入了解并高效应用 RISC-V MCU。 RVMaker 致力于推动 RISC-…

挚科龙芯机器信息

本文记录一台挚科(ZHIKE)龙芯的机器信息记录时间: 2024.12.31 机器型号:ZKL360-TF 龙芯旧世界 3A6000 集成显卡 系统信息如下 root@zhike-pc:~# cat /etc/os-release PRETTY_NAME="Loongnix GNU/Linux 20 (DaoXiangHu)" NAME="Loongnix GNU/Linux" VER…

使用已知的p、q生成私钥解rsa密文的方法

昨天渗透赛的一道题,研究了一下颇有感触,给大家分享一下(2024年的最后一天还要坐牢呜呜呜)先用rsatool根据已知的p、q生成公钥 python rsatool.py -f DER -o key.der -p 31764044218067306492147889531461768510318119973238219147743625781223517377940974553025619071173…

方差分析1.1

2 方差分析 2.1 单因素方差分析 2.1.1 分析基础 若控制变量有k个水平,不同水平下各观测变量的总体均值记为μ1,μ2,…,μk,则单因素方差分析的原假设为μ1 = μ2 = … = μk,即各总体均值都相等。 单因素方差分析认为,观测变量值的变动受到控制变量和随机变量两方面的影…

IOS FrameWorks探索

IOS里的库 https://www.jianshu.com/p/b0f58bae27db https://juejin.cn/post/6950926098595053582 静态库形式: .a和.framework 1.静态库在编译时加载,链接时会完整的复制到可执行文件中。 2.静态库的可执行文件通常会比较大,因为所需的数据都会被整合到目标代码中,因此编译…

Khronos计算加速

Khronos现行标准Khronos标准与计算、嵌入式、视觉和安全关键型市场最相关。Khronos现行标准,如图1-3所示。图1-3 Khronos现行标准Khronos计算加速标准Khronos计算加速标准,如图1-4所示。图1-4 Khronos计算加速标准机器学习加速APIKhronos机器学习加速API,如图1-5所示。 图1-…

推荐两本书《AI芯片开发核心技术详解》、《智能汽车传感器:原理设计应用》

两本书推荐《AI芯片开发核心技术详解》、《智能汽车传感器:原理设计应用》由清华大学出版社资深编辑赵佳霓老师策划编辑的新书《AI芯片开发核心技术详解》已经出版,京东、淘宝天猫、当当等网上,相应陆陆续续可以购买。该书强力解析AI芯片的核心技术开发,内容翔实、知识点新…

Khronos将软件连接到硅片和框架

Khronos将软件连接到硅片 Khronos是开放、免费的互操作性标准,利用GPU、XR和多处理器3D图形、增强和虚拟现实、并行编程、推理和视觉加速驱动的标准组织,向任何公司开放知识产权框架。 Khronos组织成立于2000年,约200名会员,其中,美洲约占40%、欧洲约占30%、亚洲约占30%,…

算法期末考试复习

o2做法 ```cpp #include<bits/stdc++.h>#define int long longusing namespace std;const int mod=1e9+7;int dp[1010][1010];int pre[1010][1010];void solve(){ int n;cin>>n; for(int i=0;i<=n;i++){ pre[0][i]=1; } for(int i=1;i<=n;i++){ for(int j=…

平淡与新鲜 - 我的2024关键词

我坐在电脑前,仔细回想这一年发生的事情,竟然有点模糊,好像我的2024不存在一样,犹如2023、2022年我已记不起来了。于是乎我紧忙翻阅手机里面的相册,试图回忆起我的2024。前言 看着朋友圈大家对2024的总结以及对2025的期待。 有人说2024年他一共走过了10几个省份,有人说20…

全球绵羊的群体结构

001、野生群体+驯化群体 002、驯化群体

.NET Aspire: Scalar displays API instance url when accessing via proxy

aspire Scalar 端口异常 解决方案app.MapScalarApiReference(options => {options.Servers = Array.Empty<ScalarServer>(); });链接 .NET Aspire: Scalar displays API instance url when accessing via proxy scalar/scalar Discussion #4025 GitHub