[异步编程] 使用 ZAsync 进行异步编程教程之一:Hello,world

ZAsync 是由吉林省左右软件开发有限公司开发的一套异步编程框架,目标是用来简化异步编程模型。

在异步编程时,我们要解决几个问题:

1、异步操作的生命周期:

  • 开启一个异步操作
  • 在后台执行异步操作
  • 异步操作执行完成
  • 回调通知异步执行结果
  • 异步操作结束清理释放

2、异步参数传递:

  • 参数的生命周期管理
  • 参数值修改问题

3、异步操作执行控制:

  • 等待异步操作完成
  • 中止异步操作执行

4、多步操作控制

  • 条件步骤
  • 重复操作
  • 中断操作
  • 参数传递

ZAsync 试图解决这一系列问题,核心是一个 IZAsyncInvoker 接口,它负责解决异步操作的生命周期的管理。

IZAsyncInvoker = interface
    ['{88A826BA-80B2-458E-80A5-CCC5522026B1}']
    procedure Cancel;
    function WaitComplete(ATimeout: Cardinal; ARaiseException: Boolean): TWaitResult;
    function RunInMainThread: IZAsyncInvoker;
    function CancelOnTimeout: IZAsyncInvoker;
    function TimeoutAfter(ATimeout: Cardinal): IZAsyncInvoker;
    function SetTimout(const ATimeout: Cardinal; ACallback: TZAsyncProc; ACancelOnTimeout: Boolean): IZAsyncInvoker;
    function Delay(AValue: Cardinal): IZAsyncInvoker;
    function Start: IZAsyncInvoker; overload;
    function Start(ARunInMainThread: Boolean; ADelay: Cardinal = 0): IZAsyncInvoker; overload;
    function Async: IZAsyncInvoker;
    function Await: IZAsyncInvoker;
    procedure Yield;
    function Follow(AInvokers: TArray<IZAsyncInvoker>; AFollowSuccessedOnly: Boolean = true): IZAsyncInvoker;
    function BeforeCancel(ACallback: TZAsyncProc): IZAsyncInvoker;
    function AfterSuccessed(ACallback: TZAsyncProc): IZAsyncInvoker;
    function AfterCanceled(ACallback: TZAsyncProc): IZAsyncInvoker;
    function AfterError(ACallback: TZAsyncProc): IZAsyncInvoker;
    function AfterDone(ACallback: TZAsyncProc): IZAsyncInvoker;
    function AfterTimeout(ACallback: TZAsyncProc): IZAsyncInvoker;
    function IsCanceled: Boolean;
    function IsComplete: Boolean;
    function IsInvoking: Boolean;
    function HasError: Boolean;
    function GetParams: TZNamedParams;
    function GetLinked: Pointer;
    procedure SetLinked(const AData: Pointer);
    function GetFlags: TZAsyncInvokeFlags;
    function HasParam(const AName: String; var AValue: TValue): Boolean;
    function GetExceptionObject: TObject;
    property Params: TZNamedParams read GetParams;
    property Linked: Pointer read GetLinked write SetLinked;
    property ExceptionObject: TObject read GetExceptionObject;
    property Flags: TZAsyncInvokeFlags read GetFlags;
  end;

IZAsyncInvoker 提供很多方法和属性来控制异步调用的过程,它是由 TZAsync.Create 方法来创建的。

那么如何创建一个IZAsyncInvoker对象呢?

    class function Create(AProc: TZAsyncProc; const AParams: TZNamedParams = []): IZAsyncInvoker; overload; static;
    class function Create(AOwner: TObject; AProc: TZAsyncProc; const AParams: TZNamedParams = [])
      : IZAsyncInvoker; overload;

上面两个方法提供了默认的实现,如果当前调用者是一个组件的话,我们可以直接使用组件的生命周期管理建立与IZAsyncInvoker之间的关联,在组件释放前,会自动调用 IZAsyncInvoker 的 Cancel 方法来取消异步操作。反之,如果异步的回调里,访问了要被释放的资源,应在资源释放前,调用 Cancel 方法来取消异步调用。

下面是一个简单的例子:

procedure TForm1.Button1Click(Sender:TObject)
begin
  TZAsync.Create(Self,
     procedure (Sender:IZAsyncInvoker)
     begin
       OutputDebugString('Hello,world');
     end,[]).Start;
end;

在上面的例子中,启动的是一个异步作业,它将在后台线程中输出 Hello,word 字符串到 Events 中。

分享到: