写了个线程,每隔一秒显示一个数字(每次加一),但不完美

前朝遗民 2015-05-26 02:38:16
写了个线程,每隔一秒显示一个数字(从0开始,每次加一)。但是发现,有时候会不显示,之后就跳过了这个数字。比如:正常情况下,会从1顺序地显示到8,但是应该显示9的时候,屏幕为空白,之后却显示10了;还有种情况,显示的时候突然为粗体显示,之后又恢复了,我并没有改变过字体字号!

效果图:







我现在把代码全部贴上,请高人帮忙看看错在哪,谢谢!

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,DateUtils;

type
TForm1 = class(TForm)
Label1: TLabel;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

TMyThread = class(TThread)
private
{ Private declarations }
FOwner: TForm;
FLastAutoCMDTime: TDateTime;

protected
procedure Execute; override;
public
constructor Create(Owner: TForm); virtual;

end;

var
Form1: TForm1;
FThread:TmyThread ;
FLastAutoCMDTime: TDateTime;
fval:longint ;
implementation

{$R *.dfm}
constructor TMyThread.Create(Owner: TForm);
begin
inherited Create(False);
FOwner := Owner;
FLastAutoCMDTime := Now;
fval:=0 ;
end;

procedure TMyThread.Execute;
begin

while not Terminated do
begin
if MilliSecondsBetween(Now, FLastAutoCMDTime) > 1000 then //每隔1秒
begin
FLastAutoCMDTime := Now;
inc(fval) ;
Tform1(FOwner).Label1.Caption:=inttostr(fval) ;
end ;
end;

end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if FThread<>nil then
begin
FThread.Terminate;
FThread.WaitFor;
FThread.Free;
end ;

end;

procedure TForm1.FormCreate(Sender: TObject);
begin
FThread:=TMyThread.Create(form1) ;

end;

end.
...全文
920 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
andylist 2015-06-12
  • 打赏
  • 举报
回复
子线程不要操作界面。
holdingsword 2015-06-12
  • 打赏
  • 举报
回复
用delphi 的时间控件不好吗?为什么自己写一个??
踏雪无痕 2015-05-31
  • 打赏
  • 举报
回复
7楼的代码,测试正常啊。
lhy 2015-05-29
  • 打赏
  • 举报
回复
使用界面线程没有同步
天行归来 2015-05-28
  • 打赏
  • 举报
回复
补充下,计算时间是否间隔一秒,用 GetTickCount 更精准,另外,线程循环体里需要做sleep,否则cpu占用率会奇高
天行归来 2015-05-28
  • 打赏
  • 举报
回复
引用 7 楼 pathletboy 的回复:
子线程中不要操作vcl,请同步到主线程执行。所以你线程部分的代码应该修改为
constructor TMyThread.Create(Owner: TForm);
begin
  inherited Create(False);
  FOwner := Owner;
  FLastAutoCMDTime := Now;
  fval:=0 ;
end;

procedure TMyThread.UpdateCaption;
begin
  Tform1(FOwner).Label1.Caption:=inttostr(fval) ;
end;

procedure TMyThread.Execute;
begin

  while not Terminated do
  begin
    if MilliSecondsBetween(Now, FLastAutoCMDTime) > 1000 then //每隔1秒
    begin
        FLastAutoCMDTime := Now;
        inc(fval) ;
        Synchronize(UpdateCaption);
    end ;
  end;

end;
如果非要访问主线程的对象,需要同步。 另外解决方案是可以用消息通知、委托等方法。
hj8090 2015-05-27
  • 打赏
  • 举报
回复
procedure TMyThread.Execute; begin while not Terminated do begin // if MilliSecondsBetween(Now, FLastAutoCMDTime) > 1000 then //每隔1秒 //begin FLastAutoCMDTime := Now; inc(fval) ; Tform1(FOwner).Label1.Caption:=inttostr(fval) ; Tform1(FOwner).Label1.Update; //end ; Sleep(1000); end; end;
「已注销」 2015-05-26
  • 打赏
  • 举报
回复
在子线程里面修改文本框的值,实际上是并不会马上刷新UI的显示,只有主线程收到相关消息的时候才会重绘UI显示。由于多个线程的执行序列是无法控制的。所以肉眼看到的东西也是不符合预期的。
pathletboy 2015-05-26
  • 打赏
  • 举报
回复
子线程中不要操作vcl,请同步到主线程执行。所以你线程部分的代码应该修改为
constructor TMyThread.Create(Owner: TForm);
begin
  inherited Create(False);
  FOwner := Owner;
  FLastAutoCMDTime := Now;
  fval:=0 ;
end;

procedure TMyThread.UpdateCaption;
begin
  Tform1(FOwner).Label1.Caption:=inttostr(fval) ;
end;

procedure TMyThread.Execute;
begin

  while not Terminated do
  begin
    if MilliSecondsBetween(Now, FLastAutoCMDTime) > 1000 then //每隔1秒
    begin
        FLastAutoCMDTime := Now;
        inc(fval) ;
        Synchronize(UpdateCaption);
    end ;
  end;

end;
lyhoo163 2015-05-26
  • 打赏
  • 举报
回复


这应该是windows的问题。
lyhoo163 2015-05-26
  • 打赏
  • 举报
回复
测试,环境与你的一样。 未曾出现屏幕为空白,有时出现粗体显示,之后又恢复了。
武稀松 2015-05-26
  • 打赏
  • 举报
回复
线程中不要直接访问界面的元素。
道玄希言 2015-05-26
  • 打赏
  • 举报
回复
將 Label1 拖大点, 然后將 AutoSize 设置为 false 就 OK 了 应该是标签在自动调整大小时出现文字显示位置不对. 我测试了你的demo, 开始也出现了你说的情况
前朝遗民 2015-05-26
  • 打赏
  • 举报
回复
我这是win7 32位 旗舰版 ,D7, 为什么会出现那问题呢? 郁闷
yct0605 2015-05-26
  • 打赏
  • 举报
回复
win7 64位 D7 测试没问题

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧