QWorker演示-在作业完成时自动调用处理函数

群里有好几个朋友要这个东西,我一直觉得不如直接在作业中自己调用的好。今晚阿木再次提起,就决定写一个辅助类给大家,供大家参考改进。这个功能就不集成到 QWorker 里了,做为一个扩展存在吧。

下面是全部代码:

type
  TQInlineJob = class
  protected
    FJobProc: TQJobProcA;
    FJobCompleteProc: TQJobProcA;
    FData: Pointer;
    FFreeType: TQJobDataFreeType;
    procedure DoJob(AJob: PQJob);
    procedure DoJobDone(AJob: PQJob);
  public
    constructor Create(AJobProc, ACompleteProc: TQJobProcA; AData: Pointer;
      ARunInMainThread: Boolean; AFreeType: TQJobDataFreeType); overload;
    destructor Destroy; override;
  end;
  { TQInlineJob }

constructor TQInlineJob.Create(AJobProc, ACompleteProc: TQJobProcA;
  AData: Pointer; ARunInMainThread: Boolean; AFreeType: TQJobDataFreeType);
begin
  inherited Create;
  FJobProc := AJobProc;
  FJobCompleteProc := ACompleteProc;
  case AFreeType of
    jdfFreeAsObject:
      TObject(FData) := AData;
    jdfFreeAsInterface:
      begin
        FData := AData;
        IUnknown(AData)._AddRef;
      end
  else
    FData := AData;
  end;
  FFreeType := AFreeType;
  Workers.Post(DoJob, Self, ARunInMainThread, jdfFreeAsObject);
end;

destructor TQInlineJob.Destroy;
begin
  if Assigned(FData) and (FFreeType <> jdfFreeByUser) then
  begin
    case FFreeType of
      jdfFreeAsObject:
        TObject(FData) := nil;
      jdfFreeAsSimpleRecord:
        Dispose(FData);
      jdfFreeAsInterface:
        IInterface(FData)._Release;
    else
      Workers.OnCustomFreeData(Workers, FFreeType, FData);
    end;
  end;
  inherited;
end;

procedure TQInlineJob.DoJob(AJob: PQJob);
begin
  try
    AJob.Data := FData;
    if Assigned(FJobProc) then
      FJobProc(AJob);
    DoJobDone(AJob);
  except
    on E: Exception do
      DoJobDone(AJob);
  end;
  AJob.Data := Self;
end;

procedure TQInlineJob.DoJobDone(AJob: PQJob);
begin
  if Assigned(FJobCompleteProc) then
    FJobCompleteProc(AJob);
end;

procedure InlineJob(AJobProc, ACompleteProc: TQJobProcA; AData: Pointer;
  ARunInMainThread: Boolean; AFreeType: TQJobDataFreeType);
begin
  TQInlineJob.Create(AJobProc, ACompleteProc, AData, ARunInMainThread,
    AFreeType);
end;

下面是调用的方式:

procedure TForm1.Button1Click(Sender: TObject);
begin
  InlineJob(
    procedure(AJob: PQJob)
    begin
      Memo1.Lines.Add('Job Executed,Data:' + IntToStr(IntPtr(AJob.Data)));
    end,
    procedure(AJob: PQJob)
    begin
      Memo1.Lines.Add('Job has done' + IntToStr(IntPtr(AJob.Data)));
    end, Pointer(100), True, jdfFreeByUser);
end;

执行的效果:

inlinejob

分享到: