窗体Form1在ShowModal时启动一个定时器,让定时器在稍后创建一个子线程Thread1,该线程负责在后台处理数据。当Thread1处理完数据之后,会通知窗体Form1,让它从ShowModal死等状态中出来,使程序继续往后运行:
Synchronize(
procedure
begin
Form1.ModalResult := mrOK;
end
);现在的问题是,时不时会发生子线程Thread1给Form1发送mrOK消息之后,Form1仍然停留在ShowModal状态死等的情况,好像Form1没有收到消息的样子。查了一下相关资料,说是“Form1.ModalResult := mrOK;”相当于PostMessage,只负责把消息成功发送出去就马上返回,不管对方有没有接收到。如何解决这个问题?感觉现在采用的同步机制很不可靠。
或者有其他更好的方法可以使用?
Synchronize(
procedure
begin
Form1.ModalResult := mrOK;
end
);现在的问题是,时不时会发生子线程Thread1给Form1发送mrOK消息之后,Form1仍然停留在ShowModal状态死等的情况,好像Form1没有收到消息的样子。查了一下相关资料,说是“Form1.ModalResult := mrOK;”相当于PostMessage,只负责把消息成功发送出去就马上返回,不管对方有没有接收到。如何解决这个问题?感觉现在采用的同步机制很不可靠。
或者有其他更好的方法可以使用?
procedure
begin
Form1.ModalResult := mrOK;
end
);如果为Form1管,这种代码意味着,可能会发生form1释放后,子线程还在跑。
另要确保timer只创建一个线程。
线程Thread1的生命周期归Form1管。该线程在Execute的最后(即声明周期快结束时)才用Synchronize来同步Form1.ModalResult的,另外Form1在ShowModal之后,还会继续处理其他一些事情,这就确保了在Form1释放之前,其子线程Thread1已经被释放。所以,你的担心不存在。
现在要解决的问题,子线程已经结束了,但Form1仍然处于ShowModal死等状态。
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;const
WM_THREADEND = WM_USER + 1;type
TForm1 = class(TForm)
btn1: TButton;
procedure btn1Click(Sender: TObject);
private
procedure OnThreadEnd(var msg: TMessage); message WM_THREADEND;
{ Private declarations }
public
{ Public declarations }
end; TTestThread = class(TThread)
private
FOwner: TObject;
protected
procedure Execute(); override;
public
constructor Create(const owner: TObject);
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.btn1Click(Sender: TObject);
var
f: TForm1;
begin
f := TForm1.Create(nil);
TTestThread.Create(f);
f.ShowModal;
end;procedure TForm1.OnThreadEnd(var msg: TMessage);
begin
Self.Close;
end;{ TTestThread }constructor TTestThread.Create(const owner: TObject);
begin
FOwner := owner;
inherited Create(False);
end;procedure TTestThread.Execute;
begin
Sleep(5000);
SendMessage((FOwner as TForm).Handle, WM_THREADEND, 0, 0);
end;
end.自己消息处理试试。
form1最好能检测线程是否结束,并做相应处理。