【发布时间】:2021-11-09 01:36:24
【问题描述】:
我想每隔一段时间更新一个标签,其中包含一个方法完成所花费的时间。我创建了一个秒表来获取经过的时间,并创建了一个 Windows 窗体计时器来通过 Tick 事件用经过的时间更新标签。我整理了一个关于我的问题的简短示例,请参见下文。
using System.Diagnostics;
using System.Threading;
using System.Windows.Forms;
namespace SOWinFormsTest
{
public partial class Form1 : Form
{
private static Stopwatch watch = new Stopwatch();
private static System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
timer.Interval = 1000;
timer.Tick += timer_Tick;
timer.Start();
watch.Start();
SomeMethod();
watch.Stop();
}
private void timer_Tick(Object sender, EventArgs e)
{
label1.Text = GetTimeString(watch.Elapsed);
}
private string GetTimeString(TimeSpan elapsed)
{
string time = string.Empty;
time = string.Format("{0:00}:{1:00}:{2:00}.{3:000}",
elapsed.Hours,
elapsed.Minutes,
elapsed.Seconds,
elapsed.Milliseconds);
return time;
}
// Mimicking a method that takes 5 seconds to complete
// My actual code could take a lot longer
private void SomeMethod()
{
Thread.Sleep(5000);
}
}
}
当我运行这个程序并单击我的按钮时,标签只更新一次,那是在 SomeMethod() 完成的 5 秒之后。我希望标签随着经过的时间每秒更新一次。有谁知道为什么这不能按预期工作?这是多线程问题吗?我需要BackgroundWorker吗?还是我完全错过了什么?
【问题讨论】:
-
注意:每次单击按钮时,都会分配多个刻度事件:
timer.Tick += timer_Tick;在构造函数中只执行一次。 -
当前您的代码正在主线程上运行。在主线程上休眠会阻塞该线程上的其他事情,包括 UI 消息泵。使用后台工作人员执行长时间任务是保持消息泵运行的关键。
-
在您删除 Button.Cllick 处理程序中的 Tick 事件订阅后(这是悲剧),
Task.Run()你的SomeMethod()。和await它。 -- 不需要string.Format()。 -
@LarsTech,已注明,感谢您的反馈!
-
@Jimi 啊哈!那是为我做的!非常感谢!
标签: c# winforms timer stopwatch