我从CodeGear的实例里整理出一个类:unit ThreadPoolUnit;interface
uses
Windows, SysUtils, Classes;
type
TObjectHelper = class helper for TObject
end; TThreadPool = class
private
type
TUserWorkItem = class
FSender: TObject;
FWorkerEvent: TNotifyEvent;
end;
class procedure QueueWorkItem(Sender: TObject; WorkerEvent: TNotifyEvent; Flags: ULONG); overload; static;
public
class procedure QueueWorkItem(Sender: TObject; WorkerEvent: TNotifyEvent); overload; static;
class procedure QueueIOWorkItem(Sender: TObject; WorkerEvent: TNotifyEvent); static;
class procedure QueueUIWorkItem(Sender: TObject; WorkerEvent: TNotifyEvent); static;
end;implementation
const
WT_EXECUTEDEFAULT = ULONG($00000000);
WT_EXECUTEINIOTHREAD = ULONG($00000001);
WT_EXECUTEINUITHREAD = ULONG($00000002);
WT_EXECUTEINWAITTHREAD = ULONG($00000004);
WT_EXECUTEONLYONCE = ULONG($00000008);
WT_EXECUTEINTIMERTHREAD = ULONG($00000020);
WT_EXECUTELONGFUNCTION = ULONG($00000010);
WT_EXECUTEINPERSISTENTIOTHREAD = ULONG($00000040);
WT_EXECUTEINPERSISTENTTHREAD = ULONG($00000080);
WT_TRANSFER_IMPERSONATION = ULONG($00000100);function QueueUserWorkItem (func: TThreadStartRoutine; Context: Pointer; Flags: ULONG): BOOL; stdcall; external kernel32 name 'QueueUserWorkItem';function InternalThreadFunction(lpThreadParameter: Pointer): Integer; stdcall;
begin
Result := 0;
try
try
with TThreadPool.TUserWorkItem(lpThreadParameter) do
if Assigned(FWorkerEvent) then
FWorkerEvent(FSender);
finally
TThreadPool.TUserWorkItem(lpThreadParameter).Free;
end;
except end;
end;{ TThreadPool }class procedure TThreadPool.QueueWorkItem(Sender: TObject; WorkerEvent: TNotifyEvent);
begin
QueueWorkItem(Sender, WorkerEvent, WT_EXECUTEDEFAULT);
end;class procedure TThreadPool.QueueIOWorkItem(Sender: TObject; WorkerEvent: TNotifyEvent);
begin
QueueWorkItem(Sender, WorkerEvent, WT_EXECUTEINIOTHREAD);
end;class procedure TThreadPool.QueueUIWorkItem(Sender: TObject; WorkerEvent: TNotifyEvent);
begin
QueueWorkItem(Sender, WorkerEvent, WT_EXECUTEINUITHREAD);
end;class procedure TThreadPool.QueueWorkItem(Sender: TObject; WorkerEvent: TNotifyEvent; Flags: ULONG);
var
WorkItem: TUserWorkItem;
begin
if Assigned(WorkerEvent) then
begin
IsMultiThread := True;
WorkItem := TUserWorkItem.Create;
try
WorkItem.FWorkerEvent := WorkerEvent;
WorkItem.FSender := Sender;
if not QueueUserWorkItem(InternalThreadFunction, WorkItem, Flags) then
RaiseLastOSError;
except
WorkItem.Free;
raise;
end;
end;
end;
end.请问如何修改可以让线程池传递参数?
如果不可以用全局变量可以么?
uses
Windows, SysUtils, Classes;
type
TObjectHelper = class helper for TObject
end; TThreadPool = class
private
type
TUserWorkItem = class
FSender: TObject;
FWorkerEvent: TNotifyEvent;
end;
class procedure QueueWorkItem(Sender: TObject; WorkerEvent: TNotifyEvent; Flags: ULONG); overload; static;
public
class procedure QueueWorkItem(Sender: TObject; WorkerEvent: TNotifyEvent); overload; static;
class procedure QueueIOWorkItem(Sender: TObject; WorkerEvent: TNotifyEvent); static;
class procedure QueueUIWorkItem(Sender: TObject; WorkerEvent: TNotifyEvent); static;
end;implementation
const
WT_EXECUTEDEFAULT = ULONG($00000000);
WT_EXECUTEINIOTHREAD = ULONG($00000001);
WT_EXECUTEINUITHREAD = ULONG($00000002);
WT_EXECUTEINWAITTHREAD = ULONG($00000004);
WT_EXECUTEONLYONCE = ULONG($00000008);
WT_EXECUTEINTIMERTHREAD = ULONG($00000020);
WT_EXECUTELONGFUNCTION = ULONG($00000010);
WT_EXECUTEINPERSISTENTIOTHREAD = ULONG($00000040);
WT_EXECUTEINPERSISTENTTHREAD = ULONG($00000080);
WT_TRANSFER_IMPERSONATION = ULONG($00000100);function QueueUserWorkItem (func: TThreadStartRoutine; Context: Pointer; Flags: ULONG): BOOL; stdcall; external kernel32 name 'QueueUserWorkItem';function InternalThreadFunction(lpThreadParameter: Pointer): Integer; stdcall;
begin
Result := 0;
try
try
with TThreadPool.TUserWorkItem(lpThreadParameter) do
if Assigned(FWorkerEvent) then
FWorkerEvent(FSender);
finally
TThreadPool.TUserWorkItem(lpThreadParameter).Free;
end;
except end;
end;{ TThreadPool }class procedure TThreadPool.QueueWorkItem(Sender: TObject; WorkerEvent: TNotifyEvent);
begin
QueueWorkItem(Sender, WorkerEvent, WT_EXECUTEDEFAULT);
end;class procedure TThreadPool.QueueIOWorkItem(Sender: TObject; WorkerEvent: TNotifyEvent);
begin
QueueWorkItem(Sender, WorkerEvent, WT_EXECUTEINIOTHREAD);
end;class procedure TThreadPool.QueueUIWorkItem(Sender: TObject; WorkerEvent: TNotifyEvent);
begin
QueueWorkItem(Sender, WorkerEvent, WT_EXECUTEINUITHREAD);
end;class procedure TThreadPool.QueueWorkItem(Sender: TObject; WorkerEvent: TNotifyEvent; Flags: ULONG);
var
WorkItem: TUserWorkItem;
begin
if Assigned(WorkerEvent) then
begin
IsMultiThread := True;
WorkItem := TUserWorkItem.Create;
try
WorkItem.FWorkerEvent := WorkerEvent;
WorkItem.FSender := Sender;
if not QueueUserWorkItem(InternalThreadFunction, WorkItem, Flags) then
RaiseLastOSError;
except
WorkItem.Free;
raise;
end;
end;
end;
end.请问如何修改可以让线程池传递参数?
如果不可以用全局变量可以么?
TMyObject = class
public
MyParam0: Integer;
MyParam1: Integer;
MyResult: Integer;
class procedure DoWorker(Sender: TObject);
end;class procedure TMyObject.DoWorker(Sender: TObject);
var
Obj: TMyObject;
begin
if Not (Sender is TMyObject) then Exit;
Obj := TMyObject(Sender); MyResult := MyParam0 + MyParam1;
end;Obj := TMyObject.Create;
Obj.MyParam0 := 100;
Obj.MyParam1 := 99;
TThreadPool.QueueWorkItem(Obj, TMyObject.DoWorker);