2014-02-19 38 views
1

我正在检查是否可以在单击按钮时在文本框中显示计时器。点击按钮时,定时器应该开始运行,并且在完成过程之后,我想停止定时器。以下是我的。我应该怎样才能使它工作?窗口计时器在文本框中

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

}   

}

请建议。

+1

什么不起作用? – LokiSinclair

+0

您能否提供有关过程的更多信息,以及您想要在文本框中显示的内容?到目前为止,您的代码看起来是有效的,但所有会发生的是每个计时器滴答,文本框文本将被替换为相同的字符串。 –

+0

另外,您正在GUI线程上调用doSomeTimeConsumingWork(),这将导致GUI在doSomeTimeConsumingWork()返回之前变得无响应。由timer1_Tick方法排队的调用将在myButton_Click方法后面等待。你应该调查BackgroundWorker类。 –

回答

1

我会用另一个Thread(或BackgroundWorker)更新TextBox(或Label)随着时间的流逝,直到工作完成。

而且我也会使用Stopwatch而不是Timer(更容易获得流逝的时间)。

代码如下;

首先,添加该字段:

private Stopwatch sw = new Stopwatch(); 

现在,添加一个BackgroundWorker更新的时间。 在BackgroundWorkerDoWork事件中,有这样的代码,以保持更新相应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(你可以创建另一个BackgroundWorker的它)增加以下内容:

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

    // Some work done here 

    sw.Stop(); 
} 
1

有几十个错误methink。

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这个?

+0

“MyClass”是不是正确的名称?他可以任何他想要的名字命名他的“形式”类。 –

+0

MyClass不是实际的名称。我用一个不同的类名粘贴了一部分代码。 – San

1

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

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

相关问题