【问题标题】:Thread safety advice when using DataGridView and BindingList in C#在 C# 中使用 DataGridView 和 BindingList 时的线程安全建议
【发布时间】:2010-12-04 06:42:33
【问题描述】:

我正在编写一个记录事件的类。我的 LogClass 实现为单例,系统中的任何类都可以写入日志条目。这些条目存储在一个列表中,当缓冲区被填满时,它们会被转储到磁盘中。

我使用 DataGridView 在执行期间显示 LogClass 的内容,因此我使用了 BindingList 以便查看器会自动更新。

我想知道我的班级的线程安全性如何。 每次我向列表中添加一个新条目时,以及当我遍历列表以将其转储到磁盘时,我都会使用“锁定”。 除了 DataGridView 之外,该类基本上是只写的,因为没有从日志中读取的选项,只能将条目添加到日志中。 转储在内部执行,这是唯一一次在 BindingList 上有明确的读取命令。

所以我真正关心的是 DataGridView 和 BindingList 发生了什么? 每次列表更改时,BindingList 都会引发一个事件。 添加新条目时这似乎不是问题,因为添加完成时会引发该事件。

我的 Dump() 代码是:

lock (lockObj) {
    foreach (LogEntry le in List) {
      writeToDisk(le)
      removeFromList(le)
    }
 }

即使我在整个迭代过程中锁定了列表,也会向查看器抛出一个事件,表明列表发生了变化(由于删除),因此被 DataGridView 读取。在更改列表时,我真的不想要任何读取/写入列表的内容。 有什么想法吗?

【问题讨论】:

标签: c# logging datagridview thread-safety bindinglist


【解决方案1】:

这不是一个真正的问题,因为一旦绑定,您只能从 Form.Invoke 方法(继承自 Control.Invoke)更改列表。如果您尝试从另一个线程更改列表,.NET 运行时会向您发出异常警告,说“无法从当前线程更改此列表”。

This 有一些你可以抓取的代码。

问候, =艾伦

【讨论】:

    【解决方案2】:

    我认为 BindingList 没有实现更改通知。在这种情况下,我认为这不是线程安全的。

    解决方案可能是使用实现 IBindingList 的自定义集合并更改列表访问器以在返回任何元素之前获取锁。

    我有一个带有更改通知的 IBindingList 的自定义实现,所以如果你愿意,我可以分享这个。(无论如何,我可能会写一篇关于代码项目的文章来描述实现..)

    【讨论】:

      猜你喜欢
      • 2013-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多