为什么计时器(system.windows.forms.timer)无法启动? [英] Why timer (system.windows.forms.timer) won't start?

查看:627
本文介绍了为什么计时器(system.windows.forms.timer)无法启动?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在用户定义的类中,我有一个计时器,当我 Timer.Enabled时,它不会启动。

Within a user-defined class, I have a timer and it just won't start when I Timer.Enabled.

用户定义的类:

  TSerialIndicator = public class
  private
    method TxTimerEvent(Sender:System.Object; e:System.EventArgs);
  public    
    Txlight:Label;
    Txtimer:System.Windows.Forms.Timer;
    constructor(mform:Form);
    method Transmit;
    method Receive;
  end;

这里是构造函数:

constructor TSerialIndicator(mform:Form);
begin
    TxLight := new Label;

    TxLight.AutoSize := false;

    TxLight.BorderStyle := BorderStyle.FixedSingle;

    TxLight.Location := new point(52,163);

    TxLight.Width := 20;
    TxLight.Height := 20;

    mform.Controls.Add(TxLight);

    TxTimer := new System.Windows.Forms.Timer;
    TxTimer.Interval:=1;

    TxTimer.Enabled:=false;
    TxTimer.Tick += new System.EventHandler(@TxTimerEvent);

    TxLight.BackColor := Color.Black;
end;

此处定义为传输方法:

method TSerialIndicator.Transmit;
begin
  TxLight.BackColor := Color.Red;

  if TxTimer.Enabled = false then
     TxTimer.Enabled:=true;
end;

这里是定义的TxTimerEvent:

Here is TxTimerEvent as defined:

method TSerialIndicator.TxTimerEvent(Sender:System.Object; e:System.EventArgs);
begin
    TxLight.BackColor := Color.Black;
    TxTimer.Enabled:=false;
end;

此处是其创建和使用方式:

Here is how it is created and used:

Slight := new TSerialIndicator(self);
Slight.Transmit;

当我从程序的其他部分调用Transmit时,它会执行其操作,但是TxTimerEvent不会永远不会开火。我什至尝试启动/停止其方法。它仍然没有执行它的Tick Event。但是,我确实注意到,当我从构造函数中启用计时器时,确实会触发TxTimerEvent ONCE。

When I call Transmit from some other part of the program, it does its thing, but TxTimerEvent won't fire at all ever. I even tried Start/Stop its methods. It still didn't execute its Tick Event. However, I did notice that when I do enable the timer from within the constructor it does fire TxTimerEvent ONCE.

我在做什么错了?

预先感谢

推荐答案

使用诸如发送和接收之类的方法名称,它可能涉及线程。就像运行SerialPort的DataReceived事件的线程池线程一样。或由于System.Timers.Timer的Elapsed事件而运行的代码。 Etcetera。

With method names like "Transmit" and "Receive", it is likely that a thread is involved. Like the threadpool thread on which a SerialPort's DataReceived event runs. Or code that runs due to a System.Timers.Timer's Elapsed event. Etcetera.

在这样的工作线程中将System.Windows.Forms.Timer的Enabled属性设置为true无效,这不是线程安全的类。它照常执行操作,创建一个隐藏的窗口,该窗口使用Windows的SetTimer()方法触发Tick事件。但是,该窗口是在不会触发消息循环的线程上创建的。因此Windows不会生成WM_TIMER消息。

Setting a System.Windows.Forms.Timer's Enabled property to true in a worker thread like that doesn't work, it is not a thread-safe class. It does what it normally does, creates a hidden window that uses Windows' SetTimer() method to get the Tick event to fire. But that window is created on a thread that doesn't pump a message loop. So Windows doesn't generate the WM_TIMER messages.

根据需要使用Control.Begin / Invoke()以确保与计时器或控件相关的任何代码都可以在UI线程上运行

Use Control.Begin/Invoke() as necessary to ensure any code that's related to timers or controls runs on the UI thread.

这篇关于为什么计时器(system.windows.forms.timer)无法启动?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆