我正在制作一个单元,在该单元中,我使用BeginThread以及在类中定义的变量来引发线程。
码:
unit practica;
interface
uses Windows;
type
TTest = class
private
public
probando: integer;
procedure iniciar_thread;
procedure load_now;
end;
implementation
procedure TTest.load_now;
begin
Sleep(probando);
end;
procedure TTest.iniciar_thread;
begin
BeginThread(nil, 0, @TTest.load_now, nil, 0, PDWORD(0)^);
end;
end.
形式:
procedure TForm1.testClick(Sender: TObject);
test:TTest;
begin
test := TTest.Create();
test.probando := 1000;
test.iniciar_thread;
end;
编译时没有错误,但是当您运行函数时,我得到以下信息:
Exception EAccessViolation in module test.exe
System Error. Code5
Runtime error 217
当我解决这个问题?
最佳答案
您不能将非静态类方法用作BeginThread()
的线程过程。查看BeginThread()
的声明:
type
TThreadFunc = function(Parameter: Pointer): Integer;
function BeginThread(SecurityAttributes: Pointer; StackSize: LongWord;
ThreadFunc: TThreadFunc; Parameter: Pointer; CreationFlags: LongWord;
var ThreadId: TThreadID): Integer;
如您所见,它期望一个独立的函数,而不是一个类方法。即使这样做,您的类方法甚至也没有正确的签名。
尝试类似这样的方法:
unit practica;
interface
type
TTest = class
private
FThread: Integer;
public
probando: integer;
procedure iniciar_thread;
procedure load_now;
end;
implementation
uses
Windows;
procedure TTest.load_now;
begin
Sleep(probando);
end;
function MyThreadFunc(Parameter: Pointer): Integer;
begin
TTest(Parameter).load_now;
end;
procedure TTest.iniciar_thread;
var
ThreadId: TThreadID;
begin
FThread := BeginThread(nil, 0, MyThreadFunc, Self, 0, ThreadId);
end;
end.
使用完所有内容后,别忘了终止线程,由
CloseHandle()
返回的线程句柄BeginThread()
和Free()
您的TTest
对象。通常,您不应该直接使用
BeginThread()
。您应该改为从TThread
派生一个类:unit practica;
interface
type
TTest = class
public
probando: integer;
procedure iniciar_thread;
end;
implementation
uses
Classes, Windows;
type
TMyThread = class(TThread)
private
FTest: TTest;
protected
procedure Execute; override;
public
constructor Create(ATest: TTest);
end;
constructor TMyThread.Create(ATest: TTest);
begin
inherited Create(False);
FreeOnTerminate := True;
FTest := ATest;
end;
procedure TMyThread.Execute;
begin
Sleep(FTest.probando);
end;
procedure TTest.iniciar_thread;
begin
TMyThread.Create(Self);
end;
end.