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

