Delphi的计时器问题:会不会造成同时操作全局变量的冲突

问题描述

Delphi的计时器问题:会不会造成同时操作全局变量的冲突

假如有一个操作是增加一个全局变量的值,但是还有一个计时器也用于定时增加该全局变量的值,那么假如在执行前一个操作的时候同时计时器也正好触发执行,这样会不会有冲突。

以下面的代码为例,假如在你点击按钮的时候同时计时器被触发会怎么样?

 unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    btn1: TButton;
    tmr1: TTimer;
    procedure btn1Click(Sender: TObject);
    procedure tmr1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  i: Integer;

implementation

{$R *.dfm}

procedure TForm1.btn1Click(Sender: TObject);
begin
  Inc(i);
  btn1.Caption:= IntToStr(i)

end;

procedure TForm1.tmr1Timer(Sender: TObject);
begin
  Inc(i);
  btn1.Caption:= IntToStr(i);

end;

end.

解决方案

Timer是一种最少计数为毫秒(1/1000秒)的计时器,它可以1毫秒,执行一次事件。

Timer基本上是两种用法:
一、定时启动,代码完成后,终止。此类问题通常情况下,不会有任何问题。

二、每天定时启动代码,完成每天的记录功能。
此类操作要注意:
1、TTimer事件中,只执行全局变量,对VCL的操作,通发送过消息。
2、不宜在TTimer事件中,执行有形的控件,特别是涉及到读写磁盘或画面的代码,代码执行时会滞留时间,会造成TTimer计量,与代码执行不同步问题。
3、在事件中调用外部程序,特别是程序中涉及控件的写画,程序会返回到事件的起步代码,因而出现“频闪”现象。即一次事件中,循环执行数十次。

procedure TForm1.tmr1Timer(Sender: TObject);
begin
Inc(i);
btn1.Caption:= IntToStr(i);
end;

虽然可以执行,但不完美。应该通过发送消息,来显示btn1.Caption。 建议改成:

procedure TForm1.Timer1Timer(Sender: TObject);
var s:string;
begin
i:=i+1;
S:=IntTostr(i);
SendMessage(Button1.handle, WM_SETTEXT, 0, LPARAM(S));
application.ProcessMessages;
end;

解决方案二:

没有问题,按钮和计时器其实在一个消息队列中,是逐个处理的。

解决方案三:

计时器是消息队列中,不会同时的!不存在并发的问题,如果是线程的话,就需要处理同步

时间: 2024-10-29 02:39:37

Delphi的计时器问题:会不会造成同时操作全局变量的冲突的相关文章

第一章-Delphi入门(四)(6)

1.4.2.1 Timer的重要属性 Enabled属性表示了计时器打开还是关闭:用Interval属性设置两个OnTimer事件间的间隔,单位是毫秒,也即千分之一秒.将间隔置为0相当于关闭计时器,Interval的最大允许值是32767,也即32.767秒. 1.4.2.2 使用Timer对程序进行控制 计时器是独立的对象,在启动与Windows无关的逻辑和应用事件时极其有用.如:用计时器可以模拟时钟或计时器,可视地显示经过的时间:可以用作系统延时,Delphi提示信息出现只需在该区域停顿几秒

第二十章-开发Delphi对象式数据管理功能(二)(5)

4. Truncate方法 该方法是通过调用BDE API函数实现的.其实现如下: procedure TBlobStream.Truncate; begin if FOpened then begin Check(DbiTruncateBlob(FDataSet.Handle, FRecord, FFieldNo, FPosition)); FModified := True; end; end; 该方法从BLOB流的当前位置起删除所有数据,并设置修改标志FModified为True.在Del

Delphi语言学习4—数据类型的基本使用

1.基本数据类型 1)Delphi自带了一些对基本类型的操作函数,如Ord ,Pred,Succ ,High,Low 2)枚举类型 声明 type Suit = (Club, Diamond, Heart, Spade);//where Ord(Club) returns 0, Ord(Diamond) returns 1... 如果枚举类型的名称和类型名重复的使用方法: type TSound = (Click, Clack, Clock)procedure TForm1.DBGridEnte

Android Wear计时器开发_Android

记得在2013年12月的时候,有系列文章是介绍怎么开发一个智能手表的App,让用户可以在足球比赛中记录停表时间.随着Android Wear的问世,在可穿戴设备中开发一款这样的App确实是个很不错的想法,但是按照目前对于Android Wear的架构了解来说,似乎有些困难.所以本系列文章我们就重写这个应用,带领大家进入Android Wear的世界. 本文不会长篇大论地讲解我们要开发的这款App的用途,因为我们在之前的系列文章已经深入了解过了.这么说吧,这是一个计时类应用,在比赛开始的时候开始执

Android Wear计时器开发

记得在2013年12月的时候,有系列文章是介绍怎么开发一个智能手表的App,让用户可以在足球比赛中记录停表时间.随着Android Wear的问世,在可穿戴设备中开发一款这样的App确实是个很不错的想法,但是按照目前对于Android Wear的架构了解来说,似乎有些困难.所以本系列文章我们就重写这个应用,带领大家进入Android Wear的世界. 本文不会长篇大论地讲解我们要开发的这款App的用途,因为我们在之前的系列文章已经深入了解过了.这么说吧,这是一个计时类应用,在比赛开始的时候开始执

C++Builder 6中开发Office程序心得(一)

一.用控件还是用OLEAutomation? 这个问题应该说很常见.我也在任何可能的情况下坚持我的主张:用BCB 6提供的Server控件组.如果你是用Delphi 6/7版本开发,那么用Delphi提供的Server控件组. 这样做有什么好处?我个人认为至少有如下两个: 第一,维护结构化+OO的程序设计风格.例如: ExcelApplication1->set_DisplayAlerts(0,false); ExcelApplication1->Quit(); 又如: int SheetCo

Linux的时钟处理机制

在 Linux 操作系统中,很多活动都和时间有关,例如:进程调度和网络处理 等等.所以说,了解 Linux 操作系统中的时钟处理机制有助于更好地了解 Linux 操作系统的运作方式.本文分析了 Linux 2.6.25 内核的时钟处理机制, 首先介绍了在计算机系统中的一些硬件计时器,然后重点介绍了 Linux 操作系 统中的硬件时钟和软件时钟的处理过程以及软件时钟的应用.最后对全文进行了 总结. 1 计算机系统中的计时器 在计算机系统中存在着许多硬件计时器,例如 Real Timer Clock

从零开始学.net多线程系列(一)

本篇涉及话题: 什么是进程 时间片 多线程的进程 线程本地存储(TLS) 中断 线程睡眠和时钟中断 线程退出/完成 什么是AppDomain 为什么你应该使用AppDomain 给AppDomain设置数据 NUnit与AppDomain 线程优先级 启动线程 回调 回顾与展望 --------------------------------------------------------------------------------------------------------------

Pomodoro Do - 拖延症患者的福音

由于完全是自己完成的应用啦,所以详细介绍就写的偏向广告一点吧-欢迎大家购买使用,并给我提意见哦-我会不断完善这款app的. App Store地址:https://itunes.apple.com/app/id791903475?ls=1&mt=8 Pomodoro Do官方主页:http://pomo.onevcat.com/ i果儿评测:Pomodoro Do--拖延症什么的,我才不怕呢 PunApp:用一顆番茄來改變你的人生 – Pomodoro Do 評測 什么是Pomodoro Do