C# DataGridView InvalidOperationException对SetCurrentCellAddressCore的可重入调用
我已经做了8个月了。直到最近,当我从数据集/数据表转移到列表时,这才是最令人烦恼的事情。现在这个问题更普遍了,我认为,因为列表似乎更有效 这个问题已经被问了好几次了,但没有一个真正理解到底发生了什么,也没有一个得到回答。奇怪的是,当调试器调出仅包含以下代码的program.cs时,我无法隔离代码中导致异常的位置:C# DataGridView InvalidOperationException对SetCurrentCellAddressCore的可重入调用,c#,datagridview,C#,Datagridview,我已经做了8个月了。直到最近,当我从数据集/数据表转移到列表时,这才是最令人烦恼的事情。现在这个问题更普遍了,我认为,因为列表似乎更有效 这个问题已经被问了好几次了,但没有一个真正理解到底发生了什么,也没有一个得到回答。奇怪的是,当调试器调出仅包含以下代码的program.cs时,我无法隔离代码中导致异常的位置: [STAThread] static void Main() { Application.EnableVisualStyles();
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MyApp());
}
应用程序异常在应用程序上。请运行。。。线路
我使用DataGridView作为后台处理日志显示。我在一个服务中有许多后台进程,可以与winform应用程序进行通信。表单侦听这些消息事件处理程序/信号器,并删除像FIFO队列这样的消息,使其不超过列表中定义的最大数量,然后我处理该消息并将其排序到BindingList[]。然后在datagrid中,如果单击某个项目,它将在文本框中显示完整消息。我已经关闭了multiselect,而且datagridview也是只读的
另外,BindingList[]从另一个控件绑定/反弹到datagrid,因此我可以选择在datagridview中显示哪个列表。这不是问题所在,因为我通过在代码中强制一个特定的列表来解决问题,但仍然存在问题
为了让它崩溃,我可以多次点击datagrid,最终它会崩溃。如果我真的想快速崩溃,我可以点击datagridview并上下滚动键盘箭头,几秒钟后就可以崩溃
我在StackOverflow上找到了描述发生了什么的内容。在其中一条评论中,它提到了一个统计数据,这是设计出来的!然而,大多数人都在谈论操纵细胞,而我并没有这样做。上面的消息与我身上发生的事情几乎相同,但程序员使用的是继承的DataGridView,因此他的解决方案对我不起作用
这与添加和删除BindingList中的项有关。如果在DataGridView中滚动/选择时发生了这两种情况之一,我可以使它崩溃。但代码非常简单:
private void DelRow( string szTableName)
{
try
{
int nProcQueue = qdList.Queue(szTableName);
MsgQueues[nProcQueue].RemoveAt(0);
this.BeginInvoke(new MethodInvoker(Refresh_dgvDetail));
}
catch (Exception ex)
{
LogEx(ex);
}
}
及
这看起来真的像一个c错误。。。我无法理解为什么微软会有这样的设计
有人知道如何阻止这种行为吗 Grek40,你说得对;我错了。我只为add做了MethodInvoker;不是删除。两者都必须这样做。基本上,任何涉及datagridview的方法都需要MethodInvoker。这是我所做的一个例子: this.InvokeMethodInvokerdelegate{MsgQueues[nCurrentQueue].removet0;}
问题消失了。将侧面的列设置为ReadOnly=true “MsgQueues”是datagridview中可见的东西吗?这些是我在DataSource=中为DGV设置的绑定列表[],是的。将RemoveAt0各自的AddoLogObject调用移动到BeginInvoke中如何。。。作用在与以下刷新相同的线程上下文中执行此更改可能更好…我已经尝试过了,但没有成功…很高兴能提供帮助。当涉及UI时,线程关联是一件大事。
private void AddRow(LogObject oLogObject, string szTableName)
{
try
{
int nQueueNumber = qdList.Queue(szTableName); // helper object to return queue number based off the name of the list
MsgQueues[nQueueNumber].Add(oLogObject);
this.BeginInvoke(new MethodInvoker(Refresh_dgvDetail));
}
catch (Exception ex)
{
LogEx(ex);
}
}