在C#中使用DataGridView和BindingList时的线程安全建议

时间:2009-10-06 13:28:29

标签: c# logging datagridview thread-safety bindinglist

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

我正在使用DataGridView在执行期间显示LogClass的内容,因此我使用BindingList以便Viewer自动更新。

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

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

我的Dump()代码是:

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

即使我在整个迭代过程中锁定了列表,也会向查看器抛出一个事件,表明列表已更改(因为删除),因此DataGridView会读取该事件。当我改变它时,我真的不希望读取/写入列表。 有什么想法吗?

2 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:1)

这并不是一个问题,因为一旦绑定,您只能从Form.Invoke方法(从Control.Invoke继承)更改列表。如果您尝试从另一个线程更改列表,那么.NET运行时将在您的w /异常情况下发出声明,说明“无法从当前线程更改此列表”。

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

此致 =艾伦