代码之家  ›  专栏  ›  技术社区  ›  Itsik

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

  •  2
  • Itsik  · 技术社区  · 15 年前

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

    我正在使用DataGridView在执行期间显示日志类的内容,因此我使用了绑定列表,以便查看器自动更新。

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

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

    dump()的代码是:

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

    即使我在整个迭代过程中锁定了列表,也会向查看器抛出一个事件,使列表发生更改(因为删除),从而被DataGridView读取。在我修改列表时,我真的不想读/写任何东西。 有什么想法吗?

    2 回复  |  直到 15 年前
        1
  •  1
  •   Community CDub    8 年前

    这实际上不是一个问题,因为一旦绑定,您只能从form.invoke方法(从control.invoke继承)更改列表。如果您试图从另一个线程更改列表,.NET运行时会对您的W/A异常发出“无法从当前线程更改此列表”的警告。

    This 有一些代码可以获取。

    当做, =艾伦

        2
  •  1
  •   kubal5003    15 年前

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

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

    我有一个带有更改通知的IBindingList的自定义实现,因此如果您愿意,我可以与您共享它。(我可能会写一篇关于代码项目的文章,描述该实现。)