【问题标题】:Is list copy thread safe?列表复制线程安全吗?
【发布时间】:2014-06-11 20:42:44
【问题描述】:

在多线程场景中使用以下模式是否安全?:

var collection = new List<T>(sharedCollection);

sharedCollection 在哪里可以同时被另一个线程修改(即添加或删除元素)?

我目前正在处理的场景是从 BindingList 复制项目,但问题应该与任何标准集合类型相关。

如果不是线程安全的,我应该锁定sharedCollection,还是有更好的解决方案?

【问题讨论】:

  • 没有关于 List&lt;T&gt; 突变是线程安全的。

标签: c# .net multithreading thread-safety


【解决方案1】:

您似乎已经回答了自己的问题。不,将更改列表复制到另一个列表不是线程安全的,是的,您可以锁定 sharedCollection。请注意,在复制时锁定sharedCollection 是不够的;您还需要在阅读或更改其内容时锁定它。

编辑:仅说明何时不好锁定您正在修改的对象-对象引用本身是否可以更改(如`sharedCollection = new List)或是否可以为空,然后创建一个单独的对象作为发生读取/写入的类的成员锁定。

【讨论】:

  • 我希望集合副本是线程安全的,因此不需要锁定。在这种情况下,我将在 GUI 线程上创建列表副本以避免锁定。
  • @AlexanderPope,当您在 GUI 线程上复制 sharedCollection 时,可以从后台线程修改它吗?如果是这样,你仍然不是线程安全的。您要么必须确保列表仅被一个线程使用,要么一直使用锁定...
  • 不,用例是根据某些标准从绑定中删除项目,为此,我需要绑定列表的副本进行迭代。我不喜欢在 gui 线程上制作副本的想法,但这似乎是最干净的方式。我知道锁定集合会导致死锁,但我想让这个问题尽可能基本。
【解决方案2】:

你可以锁定sharedCollection的SyncRoot对象。

在这里解释: Lock vs. ToArray for thread safe foreach access of List collection

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多