群里有好几个朋友要这个东西,我一直觉得不如直接在作业中自己调用的好。今晚阿木再次提起,就决定写一个辅助类给大家,供大家参考改进。这个功能就不集成到 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;
执行的效果: