我想每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);
}
答案 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线程。查看您的控件名称,它看起来像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.Threading.Timer
中的计时器非常相似,但会在UI线程上执行回调。