【说明】
IocpTask是基于Iocp引擎的多线程任务投递和处理单元,可以方便的把任务进行投递到IOCP线程进行统一调度和处理,是模仿QDAC-QWorker的处理方式,支持D7以上的版本。
【使用方法】
使用上很简单,下面解释一种比较全面的方法:
procedure PostATask(pvTaskWork:TOnTaskWork;
pvTaskData:Pointer = nil;
pvRunInMainThread:Boolean = False;
pvRunType:TRunInMainThreadType = rtSync);overload;
参数:
pvTaskWork
回调函数,procedure(pvTaskRequest: TIocpTaskRequest) of object; pvTaskRequest可以访问到传入的taskData,strData等信息。
pvTaskData
是传入的数据,为指针类型,可以是任何的数据,在回调函数中可以通过pvTaskRequest对象进行获取得到。
pvRunInMainThread:
回调函数是否在主线程中运行,考虑到一些需要访问主线程界面的任务,需要在主线程中运行。
pvRunType:
同步的方式,支持两种,一种是rtSync是使用线程的同步模式,rtPostMessage,使用消息 + Event等待的模式。消息模式考虑到dll中同步方法无法使用时可以采取的同步方式。
【注意事项】
主窗体销毁时,很多资源都已经被销毁,如果此时有投递需要主线程处理的任务,可能会导致主线程挂起,而整个进程无法结束的情况。
destructor TfrmMain.Destroy;
begin
FLogTask.PostATask(onLogMsg, 'abcd', True, rtPostMessage);
Sleep();
FLogTask.Active := false;
FLogTask.Free;
inherited Destroy;
end;
上面的代码会导致程序无法退出,FLogTask.PostATask(onLogMsg, 'abcd', True, rtPostMessage); 是投递到主线程执行的任务,这个时候主窗体正在销毁,无法相应PostMessage的消息(Synchronize方式也是一样会堵塞)导致FMessageEvent会一直等待下去,所以需要注意的是在主窗体销毁的时候不要进行主线程任务的投递。可以在主窗体的destroy中,可以禁止相应投递任务, 在主窗体析构函数的开始,设置Enable := false; 这样iocpTask不会再处理任何的任务,注意是析构函数的第一句,不是窗体的FormDestory事件。
destructor TfrmMain.Destroy;
begin
FLogTask.Enable := false;
iocpTaskManager.Enable := False; ..... inherited Destroy;
end;