在线程中创建TTimer 控件 在释放该实例时出错(50分)

  • 主题发起人 主题发起人 苍鹰
  • 开始时间 开始时间

苍鹰

Unregistered / Unconfirmed
GUEST, unregistred user!
在线程中创建TTimer 控件 在其时间响应程序中要访问VCL资源,在释放该实例时出错
线程程序如下,请问应该如何编写才完全正确。
unit Unit2;
interface
uses
Classes,windows,extctrls,Forms,SysUtils;
type
TFlash = class(TThread)
private
Time : TTimer;
Old: Integer;
I: Integer;
{ Private declarations }
protected
procedure Execute;
override;
Procedure FOnTimer(Sender: TObject);
procedure Start;
public
Constructor Create(spy: Integer);
end;

implementation
uses Unit1;
constructor TFlash.Create(spy: Integer);
begin
inherited Create(false);
Time := TTimer.Create(Application);
Time.Interval := spy ;
Time.OnTimer := FOnTimer;
Old := GetTickCount;
I := 1;
Time.Enabled := false;
end;

procedure TFlash.Execute;
begin
{ Place thread code here }
FreeOnTerminate := True;
if Terminated then
exit;
start;
end;

procedure TFlash.FOnTimer(Sender: TObject);
begin
form1.Edit1.Text := inttostr(GetTickCount - Old) ;
if GetTickCount - Old > 10000 then
begin
form1.Label1.Visible := True;
Time.Enabled := false;
if Assigned(Time) then
Time.Free;
end
else
begin
form1.label1.Visible :=odd(i);
I := I+1;
end;
end;

procedure TFlash.Start;
begin
time.Enabled := true;
end;

end.
 
在线程中直接调用VCL控件,按书上说的(参见《Delphi5程序员指南》),
是比较危险和不稳定的,所以一般不这样做。
我的办法是利用线程建立一个Form,然后再通过Form来调用VCL,
参见本论坛Since的贴子《多线程与Form的关系问题?》
我觉得那是很有道理的
 
有两个问题:
1 在Free 线程前一定要disable timer
 2 不能在FOnTimer(Sender: TObject)访问vcl,如果要访问请参见下面的用法
TMyThread.PushTheButton;
begin
Button1.Click;
end;
procedure TMyThread.Execute;
begin
...
Synchronize(PushTheButton);
...
end;


 
参考DELPHI示例:
begin
WITH MYTHREAD.CREATEdo
ONFREE:= MYFREEPROC ;
.........
END ;
PROCEDURE MYFREEPROC(SENDER:TOBJECT) ;
begin
TIMER.ENABLE := FALSE ;
END ;
 
谢谢大家的回答
 
constructor TFlash.Create(spy: Integer);
begin
inherited Create(false);
Time := TTimer.Create(Application);
Time.Interval := spy ;  //不安全,有多个线程同时访问时出现冲突
Time.OnTimer := FOnTimer; //同上
Old := GetTickCount;
I := 1;
Time.Enabled := false;
//同上
end;

procedure TFlash.Execute;
begin
{ Place thread code here }
FreeOnTerminate := True;
if Terminated then
exit;
start;//这里应改为Synchronize(start)
end;


 
同意楼上各位
要调用Synchronize(method)方法
 
to oldtiger:
"利用线程建立一个Form,然后再通过Form来调用VCL",我想这种方法也不安全,在Delphi中一切界面处理都在主线程中完成,即使你在另一个线程中创建的界面控件。
 
多人接受答案了。
 

Similar threads

后退
顶部