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.

效果图

image

posted @ 2025-03-01 17:29  殴阳疯  阅读(133)  评论(0)    收藏  举报