TextBox中的Windows计时器

时间:2014-02-19 14:58:17

标签: c# winforms timer

我正在尝试检查是否可以在单击按钮时在文本框中显示计时器。在按钮上单击计时器应该开始运行,并在完成该过程后我想停止计时器。以下是我所拥有的。我该怎么做才能让它发挥作用?

public partial class MyClass: Form

{ 
public MyClass()
{
    InitializeComponent();
    InitializeTimer();      
}

private void InitializeTimer()
{  
    this.timer1.Interval = 1000;
    this.timer1.Tick += new EventHandler(timer1_Tick);
    // don't start timer until user clicks Start            
}

private void timer1_Tick(object sender, EventArgs e)
{
    processingMessageTextBox.Invoke(new MethodInvoker(delegate { processingMessageTextBox.Text = "show running time after click"; }));
}       

private void myButton_Click(object sender, EventArgs e)
{
    this.timer1.Start();    
    doSomeTimeCOnsumingWork();
    this.timer1.Stop();    

}        

}

请建议。

3 个答案:

答案 0 :(得分:1)

有几十个错误。

MyClass不是表单的正确名称。

在计时器事件中不需要Invoke(如在UI线程中创建的那样),只需执行事件

private void timer1_Tick(object sender, EventArgs e)
{
    processingMessageLabel.Text = "show running time after click";
}

myButton_Click事件一次执行所有工作,阻止UI线程,使其更像这样(切换timer1

private void myButton_Click(object sender, EventArgs e)
{
    timer1.Enabled = !timer1.Enabled;
} 

还有什么?您想要执行doSomeTimeConsumingWork吗?为什么不使用ThreadTaskBackgroundWorker

答案 1 :(得分:1)

您对doSomeTimeConsumingWork()的调用发生在GUI线程上。 Windows窗体是单线程的 - 这意味着在doSomeTimeConsumingWork()返回之前不会为计时器提供服务。此外,正如另一个答案所提到的,没有必要将Invoke与Windows窗体定时器一起使用,因为它已经存在于GUI线程中。

调查System.Windows.Forms.BackgroundWorker类,将耗时的工作放在一个单独的线程上。 BackgroundWorker包括报告进度的机制。请参阅this MSDN article

答案 2 :(得分:1)

我会使用其他Thread(或BackgroundWorker)来更新TextBox(或Label)与已用时间,直到工作完成。

我还会使用Stopwatch代替Timer(更容易获得已用时间)。

代码如下;

首先,添加此字段:

private Stopwatch sw = new Stopwatch();

现在,添加BackgroundWorker来更新时间。 在BackgroundWorker DoWork事件中,请使用此代码,以使用已用时间更新相应的TextBoxLabel

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    while (sw.IsRunning)
    {
        // Display elapsed time in seconds.
        processingMessageTextBox.Invoke(new MethodInvoker(delegate { processingMessageTextBox.Text = (sw.ElapsedMilliseconds / 1000).ToString(); }));
    }
}

确保您的doSomeTimeCOnsumingWork正在另一个主题上运行,因此您不会阻止该用户界面。

您可以为此目的使用其他BackgroundWorker,或者只使用Thread类。

doSomeTimeCOnsumingWork(您可以为其创建另一个BackgroundWorker)中添加以下内容:

private void doSomeTimeCOnsumingWork()
{
    sw.Reset();
    sw.Start();

    // Some work done here

    sw.Stop();
}