首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >德尔菲multiThreading

德尔菲multiThreading
EN

Stack Overflow用户
提问于 2022-08-07 02:10:29
回答 1查看 207关注 0票数 3

我是新来的,所以请原谅我的问题没有在正确的位置或之前被回答。问题是用Delphi 10.4进行多线程处理.我的应用程序出现了访问违规错误,下面是一个非常简单的例子:

代码语言:javascript
复制
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;

如果不创建线程实例(这使我感到困惑),则不会出错:

代码语言:javascript
复制
procedure TForm1.Button1Click(Sender: TObject);
begin
  myThread.Create
end;

你能告诉我我错过了什么吗。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-07 03:26:01

Button1Click()中的代码是错误的。您正在将Create()作为实例方法调用到mySideTask变量上,但它没有指向有效的对象实例。您需要将Create()作为类类型本身的构造函数调用。

试一试:

代码语言:javascript
复制
procedure TForm1.Button1Click(Sender: TObject);
begin
  mySideTask := myThread.Create(False{True});
  //mySideTask.FreeOnTerminate := True;
  //mySideTask.Start;
end;

注意,我注释掉了FreeOnTerminate=True的处理。之所以如此,是因为该设置用于创建和忘记线程类型。线程将在其Execute()方法退出后自行销毁。因此,在可能随时破坏自身的线程上调用WaitFor()Free()是不安全的。

如果您想使用FreeOnTerminate=True,那么代码应该更像这样:

代码语言:javascript
复制
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;
票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73264446

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档