delphi 协程 doroutine 协程作用域
简介
一个协程可以有1个作用域,比如:.scope(form1),作用域关闭,则这个作用域下面的所有协程都会被取消并关闭;
这样就做到了 窗体关闭时 作用在这个窗体上的所有协程都会被连带关闭,不会有任何内存泄漏问题,多线程编程是难以做到的;
若一个作用域下,挂载一个协程A,这个协程A 又会衍生成百上千的子协程,此时只需要给这个协程A设置一下作用域就可以了,没有必要 A衍生的子协程也设置作用域,因为作用域关闭,A协程也就关闭,A协程衍生的所有协程都会关闭;
示例代码
两个窗体,主窗体 main和 一个 form1窗体,main创建form1,form1上衍生大量的协程,然后关闭form1,所有协程就会关闭;
主窗体的代码
unit main;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TFormMain = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
FormMain: TFormMain;
implementation
{$R *.dfm}
uses Unit1;
procedure TFormMain.Button1Click(Sender: TObject);
begin
{
动态创建一个窗体,在这个窗体上开启很多协程,然后不等协程执行完,
我们就关闭此窗体,这个作用域窗体上挂载的协程会统一立即被连带关闭
}
with TForm1.Create(nil) do //注意 AOwner要为 Nil
begin
ShowModal;
freeG; //用完窗体正常释放就行
end;
end;
procedure TFormMain.FormCreate(Sender: TObject);
begin
ReportMemoryLeaksOnShutdown := True; //若有内存泄漏让其爆出来
end;
end.
动态创建窗体的代码
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, doroutine, Vcl.StdCtrls;
type
TForm1 = class(TGorm) //这里这个窗体要继承 TGorm
Button1: TButton;
Memo1: TMemo;
Button2: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
end;
implementation
{$R *.dfm}
procedure bgSmall(go: TGo);
begin
//doSomeThing http 请求了,或其他 后台业务
OutputDebugString(PChar(Format('bgSmall...%d...http请求', [go.getInteger('index')])));
Sleep(Random(3000)); //模拟做事
end;
procedure bgBig(go: TGo);
begin
//此大协程开启3000个bg小协程做事
for var i := 1 to 3000 do
begin
go.bg(bgSmall).data('index', i).start;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
{
衍生1个bg大协程,这个协程内部又衍生300个小协程,我们只需要设置一下
这个 大协程的作用域就可以了,那300个小协程的作用域没有必要设置,因为
协程是连带关闭的,关闭父亲,父亲衍生的都会连带关闭
}
go.bg(bgBig).scope(Self).start;
end;
end.
效果图


浙公网安备 33010602011771号