我正在尝试检查是否可以在单击按钮时在文本框中显示计时器。 在按钮上单击计时器应该开始运行,该过程完成后我想停止计时器。以下是我所拥有的。我应该更改什么才能使其正常工作?
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
事件中,请使用以下代码,以根据经过的时间不断更新相应的TextBox
或Label
:
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
吗?你为什么不使用Thread
、Task
或BackgroundWorker
呢?
您对doSomeTimeConsumingWork()
的调用发生在 GUI 线程上。 Windows 窗体是单线程的 - 这意味着计时器在doSomeTimeConsumingWork()
返回之前不会提供服务。 此外,正如另一个答案所提到的,没有必要将Invoke
与 Windows 窗体计时器一起使用,因为它已经在 GUI 线程上。
调查 System.Windows.Forms.BackgroundWorker
类,将耗时的工作放在单独的线程上。 BackgroundWorker
包括报告进度的机制。 请参阅此 MSDN 文章。