每秒刷新表单

我有一个C#Windows窗体,有几个文本框和按钮。 它还有一个显示sql表的数据网格视图。 我创建了一个刷新按钮,允许我刷新表,以便我可以看到表中的更新项。 我想知道有没有办法自己刷新表。 像每10秒一样。或者不是桌子,也许整个表格每10秒加载或刷新一次?

使用Timer控件,调用UI线程并通过表单设计器为您提供控件。

private void Form1_Load(object sender, EventArgs e) { Timer timer = new Timer(); timer.Interval = (10 * 1000); // 10 secs timer.Tick += new EventHandler(timer_Tick); timer.Start(); } private void timer_Tick(object sender, EventArgs e) { //refresh here... } 

您可以使用System.Windows.Forms.Timer控件刷新表单控件。

试试这个:

 System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer(); timer1.Interval=5000;//5 seconds timer1.Tick += new System.EventHandler(timer1_Tick); timer1.Start(); private void timer1_Tick(object sender, EventArgs e) { //do whatever you want RefreshControls(); } 

我不确定这两个答案是否真的是一个好主意。 如果GUI更新(上帝要小心,但有可能,想象一下后面的Windows Update :-))会花费超过1秒的时间。 这不会导致创建线程的消息泵阻塞吗?

我刚刚在这里找到答案: 如果计时器在新的循环时间到来之前无法完成所有工作怎么办?

如果我们使用正确的Timer类,一切都很好,或者引用Jim Mischel先生:如果你正在使用System.Windows.Forms.Timer,那么在前一个完成处理之前不会发生新的勾选。

我也在tick事件开始时停止计时器并在之后再次启动它,但这只是因为我不需要连续两次更新。

通常我会使用Monitor Wait / Pulse,但在这种情况下,非常舒服,定时器事件在gui线程中执行,因此不需要调用任何东西。

因为我还需要手动更新(即不是从刻度线),我的代码看起来像这样:

在InitializeComponent()之后

  //if you use the wrong one here, you will get in great trouble :-) guiUpdateTimer = new System.Windows.Forms.Timer { Interval = 1000 }; guiUpdateTimer.Tick += (sender, args) => updateGUI(); guiUpdateTimer.Start(); 

  private void updateGUI() { guiUpdateTimer.Stop(); unsafe_updateGUI(); //inhere we actually access the gui guiUpdateTimer.Start(); } 

如果将unsafe_updateGUI()调用包装在适当的InvokeRequired检查中,甚至可以从GUI线程外部调用它。

哦,是的,对于OP场景,这很可能不是最好的方式……

这就是我经常处理的方式。

场景:某些线程应该每隔n秒更新一次,但我们希望能够在该时间耗尽之前触发更新,而不会有任何阻止任何事情的风险。

  private static readonly TimeSpan timeout = TimeSpan.FromSeconds(10); private static readonly object Synchronizer = new { }; public static void idle() { //make sure, it is only called from the Thread that updates. AssertThread.Name("MyUpdateThreadName"); lock (Synchronizer) { Monitor.Wait(Synchronizer, timeout); } } public static void nudge() { //anyone can call this lock (Synchronizer) { Monitor.PulseAll(Synchronizer); } } 

这里,idle()将从执行更新的线程调用,并且可以从任何地方调用nudge()以在超时到期之前开始更新。

由于Wait和Pulse之间的复杂交互,考虑到同步器的锁定状态,即使很多微调进入非常快,它也非常可靠。 这也具有从未死亡的整洁副作用(b)锁定更新线程。

当然,如果更新涉及GUI内容,则必须进行整个InvokeRequired之旅。 这意味着在更新线程的while循环中它看起来像

  if (MyForm.InvokeRequired) MyForm.BeginInvoke(sendinfo, message); else sendinfo(message); 

sendinfo可能是某种Action或Delegate。 而且你永远不会直接从GUI线程调用idle()!

到目前为止我能找到的唯一不那么明显的行为:如果你有很多微调,并且Thread实际上正在更新GUI,那么Invoke()和BeginInvoke()之间存在巨大差异。 根据您的需要,Invoke实际上为GUI提供了响应交互的时间,而BeginInvoke可以快速填充消息泵并使GUI不受限制(在我的情况下(奇怪的是)想要的行为:-))。