QWorker更新-新增基于作业过程的初始化和释放方法

【更新内容】

新增了一个TQJobExtData对象类型以辅助用户来创建一个自动释放的对象实例,它有匿名版本,在支持匿名函数的Delphi 2009以上程序中,可以更方便直观的编写初始化和释放过程。

一、构造函数的声明

constructor Create(AData: Pointer; AOnFree: TQExtFreeEvent); overload;
constructor Create(AOnInit: TQExtInitEvent;AOnFree: TQExtFreeEvent); overload;

constructor Create(const Value: Int64); overload;
constructor Create(const Value: Integer); overload;
constructor Create(const Value: Boolean); overload;
constructor Create(const Value: Double); overload;
constructor CreateAsDateTime(const Value: TDateTime); overload;
constructor Create(const S: QStringW); overload;
{$IFNDEF NEXTGEN}
constructor Create(const S: AnsiString); overload;
{$ENDIF}

{$IFDEF UNICODE}
constructor Create(AData: Pointer; AOnFree: TQExtFreeEventA); overload;
constructor Create(AOnInit: TQExtInitEventA;AOnFree: TQExtFreeEventA); overload;
{$ENDIF}

1、非匿名函数版本

第一种形式的声明提供了一个扩展数据成员和一个释放扩展数据成员的事件回调函数,下面的例子演示了这种代码的使用方式:

var
  AData: PComplexRecord;
begin
New(AData);
...初始化AData成员代码略...
Workers.Post(DoNullJob, TQJobExtData.Create(AData, DoFreeComplexRecord), false,
  jdfFreeAsObject);
end;

第二种形式允许您自己用过程来初始化数据成员和释放事件,看下面的例子:

procedure TForm1.DoCreateComplex(var AData: Pointer);
var
  S: PComplexRecord;
begin
New(S);
S.Name := 'Hello,QDAC';
S.Age := 3;
SetLength(S.Temp, 2);
AData := S;
end;

procedure TForm1.DoFreeComplexRecord(AData: Pointer);
begin
Dispose(PComplexRecord(AData));
end;
...
Workers.Post(DoNullJob, TQJobExtData.Create(DoCreateComplex,
  DoFreeComplexRecord), false, jdfFreeAsObject);
...

 

2、基本类型版本

为了方便日常使用,默认提供了字符串(Unicode和Ansi版本)、整数、64位整数、浮点、日期时间等类型的支持,相应的类型已经提供了默认的释放函数,使用时只需要传递类型的值作为参数就可以。

Workers.Post(DoNullJob, TQJobExtData.Create('Hello,world of QDAC'), false,
  jdfFreeAsObject);

3、匿名函数版本

对于复杂结构体等类型,使用匿名函数版本可以更直观方便一些,但象2007等早期版本并不支持匿名函数,就只能使用非匿名函数的版本。

第一种形式和非匿名函数版本一样,只有释放过程,初始化由外部代码正常初始化。

New(AData);
Workers.Post(DoNullJob, TQJobExtData.Create(AData,
  procedure(AData: Pointer)
  begin
  Dispose(PComplexRecord(AData));
  end), false, jdfFreeAsObject);

第二种形式也和匿名函数版本,有初始化和释放过程:

// 使用匿名函数初始化和释放
Workers.Post(DoNullJob, TQJobExtData.Create(
  procedure(var AData: Pointer)
  var
    S: PComplexRecord;
  begin
  New(S);
  S.Name := 'Hello';
  S.Age := 11;
  SetLength(S.Temp, 2);
  AData := S;
  end,
  procedure(AData: Pointer)
  begin
  Dispose(PComplexRecord(AData));
  end), false, jdfFreeAsObject);

【注意】上面实际上是创建了一个辅助的对象来管理生命周期,因此,必需指定释放方式以便作业能够自动释放相关的对象。

二、访问扩展数据

我们使用TQJobExtData类型替换了Data成员的值,接下来,我们需要在作业过程中访问数据成员时,也需要稍做变通,不是访问TQJob的Data成员,而是ExtData成员,并访问其相关的属性:

property Origin: Pointer read FOrigin;
property AsString: QStringW read GetAsString write SetAsString;
property AsAnsiString: AnsiString read GetAsAnsiString write SetAsAnsiString;
property AsInteger: Integer read GetAsInteger write SetAsInteger;
property AsInt64: Int64 read GetAsInt64 write SetAsInt64;
property AsFloat: Double read GetAsDouble write SetAsDouble;
property AsBoolean: Boolean read GetAsBoolean write SetAsBoolean;
property AsDateTime: TDateTime read GetAsDateTime write SetAsDateTime;

简要说明如下:

Origin:是用户原始传入的指针地址 ,如果是构造函数重载实现的基本类型,则是内部的原始指针地址,不要尝试手动释放它,它会在TQJobExtData对象释放时自动调用OnFree回调函数完成释放过程。

AsString:当你使用TQJobExtData.Create(const S:QStringW)作为构造函数创建时,通过它对扩展字符串内容访问。

AsAnsiString:当你使用TQJobExtData.Create(const S:AnsiString)作为构造函数创建时,通过对扩展字符串内容访问。

AsInteger : 当你使用TQJobExtData.Create(const AValue:Integer)作为构造函数创建时,通过它对数值内容访问。

AsInt64:当你使用TQJobExtData.Create(const AValue:Int64)作为构造函数创建时,通过它对数值内容访问。

AsFloat:当你使用TQJobExtData.Create(const AValue:Double)作为构造函数创建时,通过它对数值内容访问。

AsBoolean:当你使用TQJobExtData.Create(const AValue:Boolean)作为构造函数创建时,通过它对内容访问。

AsDateTime:当你使用TQJobExtData.CreateAsDateTime(const AValue:Integer)作为构造函数创建时,通过它对内容访问。

【注意】一定要保证访问方式和构造方式的对应关系,否则可能发生错误。

【更新级别】

可选

【特别感谢】

恢弘

分享到: