基于 QWorker 的多线程编程-使用分组作为业务处理队列

作业分组在 QWorker 中是一个重要的组成部分,它是对作业的一个二次封装,以方便上层应用进行调用。但也因为它的封装的特性,相对于直接管理可能会引入一些额外的开销,但与易用性相比,许多时候这点开销我们都忽略不计了。

在本节内容中,我们继续上一个话题,这个话题是由于根据群里广大群友实际遇到的问题,做的一个简单示例。

本示例利用 TQJobGroup 可以顺序执行的特性,将每个作业分组当成一个特定类型的作业池,当有新作业需要处理时,直接将作业加入到这个分组。

首先,我们声明 TQJobGroup 一个实例 FMyPool,作为一个处理池序列,这个池中的作业会挨个被执行。

【Delphi】

TForm1=class(TForm)
...
private
   FMyPool:TQJobGroup;
...
end;
...
procedure TForm1.FormCreate(Sender:TObject);
begin
FMyPool:=TQJobGroup.Create(True);
...
end;

【C++ Builder】

class PACKAGE TForm1:public TForm
{
...
private
   TQJobGroup *FMyPool;
...
};
...
__fastcakk TForm1::TForm1(Owner:TComponent):TForm(Owner)
{
FMyPool:=new TQJobGroup(true);
...
}

接下来的事情实际上就简单了,我们只需要在必要时,将作业直接添加到FMyPool里就可以了。

【Delphi】

procedure TForm1.DoMyJob(AJob:PQJob);
begin
OutputDebugString('My Job done');
end;

procedure TForm1.Button1Click(Sender:TObject)
begin
FMyPool.Add(DoMyJob,nil);
end;

【C++ Builder】

void __fastcall TForm1::DoMyJob(PQJob AJob)
{
OutputDebugStringW(L"My Job done");
}

void __fastcall TForm1::Button1Click(System::TObject *Sender)
{
FMyPool->Add(DoMyJob,NULL);
}

好了,如果我们需要有多个队列,那么多建几个 TQJobGroup 对象当作作业的队列处理器就好了。当然了,最后别忘了要做好犯罪现场的清理工作,防止内存泄漏:

【Delphi】

procedure TForm1.FormDestroy(Sender:TObject);
begin
FreeAndNil(FMyPool);
end;

【C++ Builder】

void __fastcall TForm1::FormDestroy(System::TObject *Sender)
{
delete FMyPool;
}

 

分享到: