Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#处理集合时线程安全的最佳实践(已经不是并发的)_C#_Multithreading_Collections_Synchronization_Thread Safety - Fatal编程技术网

C#处理集合时线程安全的最佳实践(已经不是并发的)

C#处理集合时线程安全的最佳实践(已经不是并发的),c#,multithreading,collections,synchronization,thread-safety,C#,Multithreading,Collections,Synchronization,Thread Safety,我的问题更像是我想和其他人确认的东西,所以我确信我得到了正确的答案。 当您想要执行非线程安全的操作(例如对集合进行枚举)时,最好是调用Synchronized方法(如果该集合存在) e、 g:var syncAL=ArrayList.Synchronized(myAL) 然后你就可以无忧无虑地做一些事情: foreach (var item in syncAL){ // Do something } 现在我个人并不真正使用ArrayList,这只是一个示例,但对于常规列表,Synchron

我的问题更像是我想和其他人确认的东西,所以我确信我得到了正确的答案。 当您想要执行非线程安全的操作(例如对集合进行枚举)时,最好是调用Synchronized方法(如果该集合存在)

e、 g:
var syncAL=ArrayList.Synchronized(myAL)

然后你就可以无忧无虑地做一些事情:

foreach (var item in syncAL){
  // Do something
}
现在我个人并不真正使用ArrayList,这只是一个示例,但对于常规列表,Synchronized方法并不存在,因此这里的最佳实践是:

lock (list.SyncRoot){
 // non thread-safe operation, e.g:
 list.ForEach(item => Console.WriteLine(item.ToString()));
}
当然,您可以创建自己的任意对象,但是如果您在多个类中使用某个集合对象,您需要确保在所有这些类中使用相同的对象进行锁定,这似乎是一种非常舒适的方法

我想确保这是一个真正的最佳实践,在我为我的团队添加开发技巧之前,我没有遗漏任何东西:)

我对此的理解来源:

在ArrayList中包装集合。同步包装不会使枚举线程安全,明确声明:

…即使在同步集合时,其他线程仍可以修改该集合,这会导致枚举数引发异常

所以最好的方法仍然是锁定SyncRoot,或者使用System.collections.Concurrent命名空间中的线程安全集合

ArrayList.Synchronized的内部实现只会创建内部类SyncArrayList的实例,它会为任何操作锁定SyncRoot,如下所示:

  public override int Add(object value)
  {
    lock (this._root)
      return this._list.Add(value);
  }
然后你就可以无忧无虑地做一些事情:

foreach (var item in syncAL){
  // Do something
}
编号:发件人:

通过集合枚举本质上不是线程安全的过程。即使集合已同步

至于核心问题:

我想确保这确实是最好的做法


不,这是一种过时的做法。请注意,SyncRoot仅限于
ICollection
,而
ICollection
不支持它。较新的集合(
List
)不支持它,这是您的主要线索

谢谢你的快速回答