计时器.Elapsed事件只能触发一次,我想每秒触发一次。

3

使用 Timers.Timer 来创建计时器。我使用 Timer.Elapsed 来处理事件,在特定时间后显示时间。我将计时器间隔设为 1,并启用 AutoReset。但问题是事件仅触发一次,我只能在文本框中获取一次时间。如何每秒更改文本框中的时间?我尝试了所有替代方法,但没有成功...谢谢。

    System.Timers.Timer StopWatchTimer = new System.Timers.Timer();
    Stopwatch sw = new Stopwatch();
     public void StopwatchStartBtn_Click(object sender, ImageClickEventArgs e)
    {

        StopWatchTimer.Start();
        StopWatchTimer.Interval = 1;
        StopWatchTimer.Enabled = true;
        StopWatchTimer.AutoReset =true; 
        sw.Start();
        StopWatchTimer.Elapsed += new System.Timers.ElapsedEventHandler(StopWatchTimer_Tick);
    }

    protected void StopWatchStopBtn_Click(object sender, ImageClickEventArgs e)
    {

        TextBoxStopWatch.Text = "00:00:000";
        StopWatchTimer.Stop();
        sw.Reset();
        sw.Stop(); 

    }

    public void StopWatchTimer_Tick(object sender,EventArgs e)
    {           
   TextBoxStopWatch.Text=   Convert.ToString(sw.Elapsed);
    }

更新: 我尝试通过在Visual Studio中创建新的网站来解决问题,但仍然没有成功。问题仍然存在。现在的更新是当我在代码的某一行设置断点时

     TextBoxStopWatch.Text=   Convert.ToString(sw.Elapsed);

文本在不断变化,但没有显示在文本框中。希望您能理解这一点。


当我运行你的代码时,我得到了一个InvalidOperationException。原因是StopWatchTimer_Tick方法试图访问不同线程中的控件。你的其余代码是什么? - NotMe
有趣的是,如果我直接编译和运行它(在VS之外),它会按预期工作。你使用的C#版本是什么? - NotMe
@Chris Lively .NET Framework 4.0 - Hiren
我注意到你提到这是在一个Web应用程序中发生的。难怪你没有像我一样在运行时收到错误。请看下面我的答案。在Web应用程序中无法这样做。 - NotMe
4个回答

5

您在设置参数之前就调用了Start()。请尝试以下操作:

StopWatchTimer.Interval = 1000; 
StopWatchTimer.AutoReset = true; 
StopWatchTimer.Elapsed += new System.Timers.ElapsedEventHandler(StopWatchTimer_Tick); 
StopWatchTimer.Enabled = true; 

在设置完所有属性后,将Enabled属性设置为true。(调用Start()方法相当于设置Enabled = true)

另外,不知道您是否意识到,Timer.Interval属性的单位是毫秒。因此,您每毫秒都会触发Timer.Elapsed事件。仅供参考。


谢谢你的回答。在启动之前,我应该设置属性。我已经这样做了,但是仍然只能在文本框中获取一次值,然后它就不会触发事件了。 - Hiren
尝试将您的间隔设置为1000。而且,您怎么知道Timer.Elapsed事件只会触发一次? - user596075
实际上我在那里设置了断点...将它设置为1000后,我甚至一次都没有得到过。 - Hiren
@Hiren 可能会导致这个问题。我不能确定。请取消断点并尝试一下。 - user596075
1
将StopWatchTimer.Enabled = true设置为true与调用Start函数相同。根据MSDN的说法:“将Enabled设置为true等同于调用Start,而将Enabled设置为false等同于调用Stop。” - ahawker
@Hiren,请看我的修改。设置“Enabled = true”实际上会使你的事件启动。请查看我在帖子中的代码,并尝试一下。你不需要调用“Start()”,并且设置“Enabled = true”。只需在设置完属性和事件处理程序后设置“Enabled = true”。 - user596075

3

在网页中你不能用这种方法来实现。

当页面被渲染时,服务器已经完成并且客户端已经断开连接。它将不再接收到来自计时器的任何更新。

如果您需要在页面上显示一个定时器以展示一些数字变化,则必须通过javascript来实现。


1
你还需要考虑到文本框的内容只能由UI线程而不是回调上下文来修改。你在回调中是否遇到了异常?可以尝试使用dispatcher在主UI线程上调用UI更新,而不是定时器线程。

0
以下方法适用于我。我重新排列了代码,以便计时器/秒表的设置仅设置一次,避免混淆,并处理了UI线程调用。
    System.Timers.Timer timer;
    Stopwatch stopwatch;

    public Form1()
    {
        InitializeComponent();

        timer = new System.Timers.Timer();
        timer.Interval = 1000;
        timer.AutoReset = true;
        timer.Elapsed += new ElapsedEventHandler(TimerElapsed);

        stopwatch = new Stopwatch();
    }

    public void TimerElapsed(object sender, EventArgs e)
    {
        TextBoxStopWatch.Text = Convert.ToString(stopwatch.Elapsed);
    }

    private void btnStart_Click(object sender, EventArgs e)
    {
        timer.Start();
        stopwatch.Start();
    }

    private void btnStop_Click(object sender, EventArgs e)
    {
        TextBoxStopWatch.Text = "00:00:000";
        timer.Stop();
        stopwatch.Reset();
        stopwatch.Stop();
    }

嗨,感谢回复。我正在处理Web应用程序,而不是Windows应用程序,因此我没有Invoke或InvokeRequired。 - Hiren

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接