读取时.NET中的跨线程安全性,但不更新DataGridView控件

时间:2014-06-09 18:45:58

标签: c# multithreading winforms datagridview invokerequired

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

示例:我在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;
        }
    }

2 个答案:

答案 0 :(得分:5)

缺少InvalidOperationException 证明线程安全。 Winforms仅对非常特定的成员访问执行检查。它必须涉及Handle属性,用于底层操作系统调用。这将在您的代码中永远发生,DataGridView不会从Windows调用中获取其数据。

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

然后,DataGridViewCell如何获取其值非常重要。非显而易见的情况是它引发CellValueNeeded事件或网格是数据绑定的情况。现在它完全取决于 代码是否是线程安全的。

答案 1 :(得分:2)

这不安全。

控件,尤其是dataGrid,将使用引擎盖下的Collection类。当其他线程可能编辑时,它们不安全。

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