如何使用计时器清除datagridview?

时间:2017-12-05 05:58:15

标签: c# multithreading

我想每10秒更新一次datagridview。更新后到目前为止,添加了新行,我想在更新之前清理datagridview。

问题在于,当我在OnCallBack() dataGridView2.Rows.Clear();dataGridView2.Refresh();内部打电话时,我得到一个例外:

  

跨线程操作无效

我试图调用它,但它没有帮助。

 if(dataGridView2.InvokeRequired){
        dataGridView2.Invoke(new MethodInvoker(delegate{
        dataGridView2.Rows.Clear();
        dataGridView2.Refresh();
 }));

我的代码:

    private void Live(){
        timer = new System.Threading.Timer (_ => OnCallBack(), null, 1000,Timeout.Infinite); 
    }

    private void OnCallBack()
    {
        timer.Dispose();
        counter--;

        label8.Text = counter.ToString();          
        if (counter == 0){
                string[] pr = {"124"};
                search.SearchLive(pr, dataGridView2, label10);
                counter = 10;
        }
        timer = new System.Threading.Timer (_ => OnCallBack(), null, 1000,Timeout.Infinite);
     }

2 个答案:

答案 0 :(得分:0)

您可以使用System.Timers类创建新计时器及其间隔

 System.Timers.Timer timer1 = new System.Timers.Timer();
 timer1.Interval = 1000; //time after which you want to clear datagrid
 timer1.Start();
 timer1.Elapsed += TimerTick;

然后为TimerTick

创建一个事件处理程序
private void TimerTick(object sender, ElapsedEventArgs e)
{
   if (dataGridView1.rows.count>0)
   {
     dataGridView1.Rows.Clear();
     dataGridView1.Refresh();
   }
}

如果要阻止进一步的串扰异常,请添加此检查

CheckForIllegalCrossThreadCalls = false;

答案 1 :(得分:0)

您只能从UI线程访问UI组件。 Threading.Timer将在线程池的线程上执行回调,而不是UI线程,从而导致异常。但是有办法将函数调用分派给UI线程。

发送对UI线程的调用

大多数UI框架都是完全单线程的。不允许从与UI线程不同的线程访问任何组件。

您需要调度到当前的UI线程。查看您的控件名称,它看起来像WinForms或WPF应用程序。

在WinForms中,您需要以下代码才能发送回UI线程:

public void UpdateUI(object parameter)
{
    if (this.InvokeRequired)
    {
       Dispatcher.BeginInvoke(new Action(() => UpdateUI(parameter)));
        return;
    }

    // Update or access here 
}

在WPF中,以下剪辑允许您将ui格式更改为其他线程:

public void UpdateUI(object parameter)
{
    if (!Dispatcher.CheckAccess())
    {
       Dispatcher.BeginInvoke(new Action(() => UpdateUI(parameter)));
       return;
    }

    // Do update or access here
}

这里需要注意的重要一点是,这些函数将在UI线程上执行,而不是在调用线程上执行。

编辑:对象参数是完全可选的。它旨在作为如何将此方法与带参数的函数一起使用的示例。

使用System.Timers.Timer

你也可以使用System.Timers.Timer,它与System.Threading.Timer中的计时器非常相似,但会在UI线程上执行回调。