文本框中的窗口计时器



我正在尝试检查是否可以在单击按钮时在文本框中显示计时器。 在按钮上单击计时器应该开始运行,该过程完成后我想停止计时器。以下是我所拥有的。我应该更改什么才能使其正常工作?

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();    
}        

}

请指教。

我会使用另一个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另一个线程上运行,这样就不会阻止 UI。

您可以使用其他BackgroundWorker来实现此目的,也可以只使用Thread类。

doSomeTimeCOnsumingWork(可以为其创建另一个后台辅助角色)中添加以下内容:

private void doSomeTimeCOnsumingWork()
{
    sw.Reset();
    sw.Start();
    // Some work done here
    sw.Stop();
}

我认为有十几个错误。

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呢?

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

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

最新更新