每秒刷新一次表单
本文关键字:一次 表单 刷新 | 更新日期: 2023-09-27 17:58:43
我有一个C#Windows窗体,它有几个文本框和按钮。此外,它还有一个显示sql表的datagrid视图。我创建了一个刷新按钮,允许我刷新表,这样我就可以看到表中更新的项目。我想知道有没有办法自己刷新桌子。就像每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();
}
这是我通常处理它的方式。
场景:一些线程应该每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()将从执行更新的线程调用,轻推()可以从任何位置调用,以便在超时到期之前启动更新。
考虑到同步器的锁定状态,由于等待和脉冲之间的复杂交互,即使在很多轻推非常快的情况下,它也能非常可靠地工作。这还有一个巧妙的副作用,那就是锁定更新线程。
当然,如果更新涉及GUI内容,您将不得不进行整个InvokeRequired之旅。这意味着在更新线程的while循环中,它看起来有点像
if (MyForm.InvokeRequired)
MyForm.BeginInvoke(sendinfo, message);
else
sendinfo(message);
sendinfo可能是某种Action或Delegate。而且您永远不会直接从GUI线程调用idle()!
到目前为止,我能发现的唯一不那么明显的行为:如果你有很多非常快的轻推,而线程实际上正在更新GUI,那么Invoke()和BeginInvoke(。根据您的需要,Invoke实际上为GUI提供了对交互做出反应的时间,BeginInvoke可以快速淹没消息泵,使GUI不受干扰(在我的情况下,这是(奇怪的)所需的行为:-))。
我不确定这两个答案是否真的是个好主意。如果GUI更新(上帝要小心,但这是可能的,想象一下后台的Windows更新:-))耗时超过1秒会发生什么。这不会导致创建线程的消息泵堵塞吗?
我刚刚在这里找到了答案:如果计时器不能在新的周期时间到来之前完成所有工作,该怎么办?
如果我们使用正确的Timer类,一切都很好,或者引用Jim Mischel先生的话:如果你使用的是System。Windows。表格。计时器,则在上一个刻度完成处理之前不会出现新的刻度。
我也会在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();
}
如果将unsaf_updateGUI()调用封装在正确的InvokeRequired检查中,则甚至可以从GUI线程外部调用它。
哦,是的,对于OP场景来说,这很可能不是最好的方式。。。