0

虽然关于使用 Control.Invoke 从工作线程更新 GUI 控件的问题/答案有很多,但我无法清楚地了解从控件读取数据而不更新它的主题。

示例:我在 Windows 窗体上有一个 DataGridView。从工作线程中,我想检查 DGV 上特定单元格的值,但我不需要/不想更新该值。从工作线程中,我调用一个方法,该方法将 DataGridView 对象作为其唯一参数,然后该方法检查 DataGridView 中的特定单元格但不修改它,在这种情况下我需要使用 .Invoke 吗?

现在,如果不使用 .Invoke,代码似乎运行良好,没有明显的警告。但是,我不清楚这是否安全,因为它不会更新 DGV,而是只查看 DGV 的单元而不修改任何单元。

有人可以对此有所了解吗?如果这是一个重复的问题,我很抱歉,但我找不到任何其他问题,这些问题专注于在多线程情况下只阅读控件而不更新/修改它。

谢谢。

从工作线程调用的示例方法:

    private DataGridViewRow getRowObject(DataGridView dgv)
    {
        foreach (DataGridViewRow row in dgv.Rows)
        {
                if ((int)dgv[specialColumn, row.Index].Value == 100)                    
                return row;
        }
    }
4

2 回答 2

6

没有 InvalidOperationException 并不能证明线程安全。Winforms 只检查非常具体的成员访问。它必须涉及在底层操作系统调用中使用的 Handle 属性。这永远不会在您的代码中发生,DataGridView 不会从 Windows 调用中获取其数据。

它不是线程安全的一个明显情况是您允许用户继续编辑网格值。您当然会得到一个与线程执行完全不同步的不可预测的值。您必须将 DataGridView.ReadOnly 属性设置为true以防止这种情况发生。

那么 DataGridViewCell 如何获得它的值就非常重要了。不明显的情况是它引发 CellValueNeeded 事件或网格是数据绑定的情况。现在这完全取决于代码是否是线程安全的。

于 2014-06-09T19:06:01.567 回答
2

这是不安全的。

控件,尤其是他的 dataGrid,将在后台使用 Collection 类。当其他线程可能编辑时,它们不安全阅读。

读取某些属性(即 SelecteItem)将需要一个句柄并触发跨线程警告异常。

于 2014-06-09T18:54:05.167 回答