【问题标题】:DataGridView InvalidOperationException reentrant call to SetCurrentCellAddressCoreDataGridView InvalidOperationException 可重入调用 SetCurrentCellAddressCore
【发布时间】:2017-06-09 11:18:24
【问题描述】:

我已经为此工作了大约 8 个月。直到最近,当我从 DataSet / DataTables 转移到列表时,这比任何事情都令人烦恼。现在问题更加普遍(我认为是因为列表似乎更有效率)。

这个问题已经被问过好几次了,但他们都没有真正了解真正发生了什么(也没有人回答)。奇怪的是我无法在我的代码中找出导致异常的位置,因为调试器会调出只有这段代码的 program.cs:

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new MyApp());

    }

应用程序异常位于 Application.Run... 行。

我使用 DataGridView 作为后台处理日志显示。我在服务中有许多后台进程,这些进程与 Winform 应用程序进行通信。表单监听这些消息(事件处理程序/信号器)并删除消息(如 FIFO 队列)以不超过列表中定义的最大数量,然后我处理消息并将它们排序到 BindingList []。然后在数据网格中,如果我单击一个项目,它将在文本框中显示完整的消息。我再次关闭了多选,datagridview 是只读的。

另外,BindingList[] 从另一个控件绑定/反弹到数据网格,因此我可以选择要在数据网格视图中显示的列表。这不是问题,因为我通过在代码中强制使用单个特定列表来解决问题,但仍然存在问题。

为了让它崩溃,我可以多次点击数据网格,最终它会崩溃。如果我真的想快速崩溃,我点击 datagridview 并上下滚动(键盘箭头),我可以在几秒钟内崩溃。

我在 StackOverflow 上找到了描述正在发生的事情的 this article (click here)。在其中一个 cmets 中,它指的是 Microsoft Bug Report(click here),它表明这是设计使然!然而,大多数人都在谈论操纵我没有做的细胞。最上面的消息与发生在我身上的几乎相同,但程序员使用的是继承的 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); 
        }
    }

    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);
        }
    }

这看起来真的像一个 c# 错误...为什么 MS 会按照设计的那样做这超出了我的范围...?

有人知道如何阻止这种行为吗?

【问题讨论】:

  • 'MsgQueues' 是在你的 datagridview 中可见的吗?
  • 这些是我在 DataSource= 中为 DGV 设置的 BindingLists[],是的。
  • 如何将RemoveAt(0) 各自的Add(oLogObject) 调用移到BeginInvoke(...) 函数中?在与以下刷新相同的线程上下文中执行此更改可能会更好...
  • 我已经尝试过了,但没有成功...

标签: c# datagridview


【解决方案1】:

Grek40,你是对的;我错了。我做了 MethodInvoker 只是为了添加;不是删除。两者都必须这样做。基本上任何触及 datagridview 的方法都需要有 MethodInvoker。这是我所做的一个例子:

this.Invoke((MethodInvoker)delegate { MsgQueues[nCurrentQueue].RemoveAt(0); });

问题消失了。

【讨论】:

  • 很高兴为您提供帮助。当涉及到 UI 时,线程关联是一件大事。
【解决方案2】:

设置侧边的列为ReadOnly = true;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-04
    • 2017-06-04
    • 2017-01-27
    • 2016-01-15
    • 2016-01-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多