以线程安全的方式枚举列表
本文关键字:枚举 列表 方式 线程 安全 | 更新日期: 2023-09-27 18:30:47
假设我在一个类中有一个列表,它将用于多线程方案。
public class MyClass
{
List<MyItem> _list= new List<MyItem>();
protected object SyncRoot {
get {
return ((IList)_list).SyncRoot;
}
}
public void Execute1()
{
lock(SyncRoot)
{
foreach(var item in _list) DoSomething(item);
}
}
public void Execute2()
{
Item[] list;
lock(SyncRoot)
{
list=_list.ToArray();
}
for(var i=0;i<list.Length;i++) DoSomething(list[i]);
}
}
Execute1 方法是以线程安全的方式枚举列表的"正常"方法。但是 Execute2 呢?这种方法是否仍然是线程安全的?
在这两种情况下,对列表(副本)的访问都是线程安全的。但是,当然,MyItem 元素不会以任何方式同步。
第二种形式看起来有点贵,但它允许在DoSomething()
运行时对原始表单进行添加/删除。 该数组的作用类似于一种快照,如果它符合您的要求,它可能会很有用。请注意,您不妨使用 ToList()
.
只要
_list
的所有其他使用也受到相同的lock
语句保护,它就是安全的。您正在独占访问列表,复制其内容,然后处理副本(由于范围限定,您也具有独占访问权限)。乍一看有点浪费,但在某些情况下是一种合法的方法。