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;