第一个定义:
uses
Windows;
type
TThreadParams = record
FParam1 : Integer;
FParam2 : array [0..511] of Byte;
end;
TFoo = class
private
FThreadHandle: THandle;
FThreadID : Cardinal;
FSomeParameters: TThreadParams;
function procInObject(const Params: Pointer): DWord; stdcall;
public
procedure CreateObjThread;
end;
function procInInterface(const Params: Pointer): DWord; stdcall;
implementation
function procInInterface(const Params: Pointer): DWord;
begin
Result := High(Cardinal);
while True do
begin
//Do something with Params
end;
end;
{ TFoo }
procedure TFoo.CreateObjThread;
begin
FThreadHandle := CreateThread(nil, 0, @procInInterface, @FSomeParameters, CREATE_SUSPENDED, FThreadID);
//FThreadHandle := CreateThread(nil, 0, @procInObject, Self, CREATE_SUSPENDED, FThreadID);
end;
function TFoo.procInObject(const Params: Pointer): DWord;
begin
Result := High(Cardinal);
while True do
begin
//Do something with Params
end;
end;
现在,正如您所看到的,我正在尝试使用WinAPI创建一个匿名线程。我不想使用TThread类或像Omni这样的库。
问题出在我做的时候
procedure TFoo.CreateObjThread;
begin
FThreadHandle := CreateThread(nil, 0, @procInInterface, @FSomeParameters, CREATE_SUSPENDED, FThreadID);
//FThreadHandle := CreateThread(nil, 0, @procInObject, Self, CREATE_SUSPENDED, FThreadID);
end;
代码编译,当我做
procedure TFoo.CreateObjThread;
begin
//FThreadHandle := CreateThread(nil, 0, @procInInterface, @FSomeParameters, CREATE_SUSPENDED, FThreadID);
FThreadHandle := CreateThread(nil, 0, @procInObject, Self, CREATE_SUSPENDED, FThreadID);
end;
它没有。编译器说“[DCC错误] Unit1.pas(45):E2036需要变量”。所以出现了一个问题;我是否必须使用在Unit接口中声明的一些方法而不是一个对象的类,以便实现我想要的东西?那些使 procInInterface 变量而 procInObject 没有的捕获量是什么?
另一方面,它能够编译
procedure TFoo.CreateObjThread;
begin
FThreadHandle := CreateThread(nil, 0, @TFoo.procInObject, Self, CREATE_SUSPENDED, FThreadID);
end;
但这对我来说似乎不合适。这种方式是否会导致TFoo的所有实例使用 procInObject 的相同代码块,而不是拥有自己的代码块?我哪里错了?
答案 0 :(得分:2)
您认为多个线程运行相同的代码块是不合适或错误的,这是错误的。这绝对没问题,经常做。代码(除非自我修改)本质上是线程安全的。
不确定为什么你需要一个单独的记录/类用于线程参数,而不是简单地使用TFoo的字段,但我想这是你的设计:)。
将'ProcInInterface'中的参数强制转换回TFoo,你应该没问题。
你可能意识到你需要注意释放TFoo,要么确保线程被终止,要么确保线程被终止,或者从不明确释放它并允许操作系统在应用程序关闭时终止它。 / p>
你对TThread类有什么看法(除了你不必使用的可怕的同步/ WaitFor / OnTerminate)?
答案 1 :(得分:2)
您无法传递实例方法,因为它是错误的类型。您尝试使用procInObject
永远不会有效。
线程过程是一个简单的过程,它不是类的方法。为了将实例放入您的线程,您需要使用Params参数传递它。
线程函数如下所示:
function ThreadProc(Params: Pointer): DWORD; stdcall;
var
Obj: TFoo;
begin
Obj := TFoo(Params);
....
end;
该程序现在可以调用Obj
上的方法。
对CreateThread
的调用:
procedure TFoo.CreateObjThread;
begin
FThreadHandle := CreateThread(nil, 0, @ThreadProc, Self, CREATE_SUSPENDED, FThreadID);
end;