winforms 每秒刷新表单

f2uvfpb9  于 2023-10-23  发布在  其他
关注(0)|答案(4)|浏览(94)

我有一个C# Windows窗体,它有几个文本框和按钮。它也有一个datagrid视图,显示了一个sql表。我创建了一个刷新按钮,它允许我刷新表,这样我就可以看到表中更新的项。我想知道有没有什么方法可以自己刷新table。比如每10秒一次,或者不是表,而是整个表单每10秒一次加载或刷新?

57hvy0tb

57hvy0tb1#

使用Timer控件,它的UI线程被调用,并且是一个可通过窗体设计器使用的控件。

private void Form1_Load(object sender, EventArgs e)
{
    System.Windows.Forms.Timer timer1 = new System.Windows.Forms.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...
}
093gszye

093gszye2#

您可以使用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();
}
m4pnthwp

m4pnthwp3#

这是我通常处理它的方式。
场景:一些线程应该每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()将从执行更新的Thread调用,而nudge()可以从任何地方调用,以便在超时到期之前开始更新。
由于等待和脉冲之间的复杂相互作用-考虑到同步器的锁定状态,它的工作非常可靠,即使在很多轻推非常快的时候。这也有一个很好的副作用,即永远不会死(B)锁定更新线程。
当然,如果更新涉及GUI的东西,你将不得不采取整个PickeRequired之旅。这意味着在更新线程的while循环中,

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

sendinfo可能是某种Action或Delegate。而且你永远不会直接从GUI线程调用idle()!
到目前为止,我能找到的唯一不那么明显的行为是:如果你有很多nudges非常快,线程实际上是更新一个GUI,有一个巨大的差异之间的nudges()和Beginnudges()。根据你想要的,Brackke实际上给了GUI时间来对交互做出React,BeginBrackke可以快速地淹没消息泵,使GUI无法响应(在我的情况下,这是(奇怪的是)想要的行为:-))。

y1aodyip

y1aodyip4#

我不确定这两个答案是否真的是一个好主意。如果GUI更新(上帝保佑,但这是可能的,想象一下后台的Windows更新:-)花费超过1秒的时间会发生什么。这不会导致从创建线程的消息泵堵塞吗?
我在这里找到了答案:What if a timer can not finish all its works before the new cycle time arrives?
如果我们使用了正确的Timer类,一切都很好。吉姆·米歇尔:如果您使用的是System.Windows.Forms.Timer,则在前一个刻度完成处理之前,不会出现新的刻度。
我还在tick事件开始时停止计时器,然后再次启动它,但这只是因为我不需要连续两次更新。
通常我会使用Monitor Wait/Pulse,但在这种情况下,它非常舒适,计时器事件在gui线程中执行,所以没有必要做任何事情。
因为我也需要手动更新(即。不是从tick开始的),我的代码看起来像这样:
在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()调用 Package 在适当的sockeRequired检查中,则甚至可以从GUI线程外部调用它。
哦,是的,对于OP场景,这可能不是最好的方式去.

相关问题