我是新来的,所以请原谅我的问题没有在正确的位置或之前被回答。问题是用Delphi 10.4进行多线程处理.我的应用程序出现了访问违规错误,下面是一个非常简单的例子:
type
myThread = class(TThread)
protected
procedure Execute; override;
end;
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
mySideTask : myThread;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
with mySideTask.Create do
FreeOnTerminate:=True
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if mySideTask<>nil then
begin
mySideTask.Terminate;
mySideTask.WaitFor;
FreeAndNil(mySideTask);
end;
end;
{ myThread }
procedure myThread.Execute;
begin
Synchronize(
procedure
begin
Form1.Memo1.Lines.Add('running my side task')
end);
end;如果不创建线程实例(这使我感到困惑),则不会出错:
procedure TForm1.Button1Click(Sender: TObject);
begin
myThread.Create
end;你能告诉我我错过了什么吗。
发布于 2022-08-07 03:26:01
Button1Click()中的代码是错误的。您正在将Create()作为实例方法调用到mySideTask变量上,但它没有指向有效的对象实例。您需要将Create()作为类类型本身的构造函数调用。
试一试:
procedure TForm1.Button1Click(Sender: TObject);
begin
mySideTask := myThread.Create(False{True});
//mySideTask.FreeOnTerminate := True;
//mySideTask.Start;
end;注意,我注释掉了FreeOnTerminate=True的处理。之所以如此,是因为该设置用于创建和忘记线程类型。线程将在其Execute()方法退出后自行销毁。因此,在可能随时破坏自身的线程上调用WaitFor()或Free()是不安全的。
如果您想使用FreeOnTerminate=True,那么代码应该更像这样:
type
myThread = class(TThread)
protected
procedure Execute; override;
end;
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
mySideTask : myThread;
procedure SideTaskTerminated(Sender: TObject);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
mySideTask := myThread.Create(True);
mySideTask.FreeOnTerminate := True;
mySideTask.OnTerminated := SideTaskTerminated;
mySideTask.Start;
end;
procedure TForm1.SideTaskTerminated(Sender: TObject);
begin
mySideTask := nil;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if mySideTask <> nil then
begin
mySideTask.FreeOnTerminate := False;
mySideTask.Terminate;
mySideTask.WaitFor;
FreeAndNil(mySideTask);
end;
end;
{ myThread }
procedure myThread.Execute;
begin
Synchronize(
procedure
begin
Form1.Memo1.Lines.Add('running my side task')
end);
end;https://stackoverflow.com/questions/73264446
复制相似问题