Jef*_*eff 5 c# list generic-list thread-safety
我是一个线程菜鸟,我正在尝试用C#(.NET 3.5 SP1)编写一个自定义线程安全通用列表类.我已经阅读了为什么线程安全集合如此困难?.在查看了类的要求后,我想我只需要安全地添加到列表中并返回列表.该示例几乎显示了我想要的所有内容,但它缺少返回列表方法,因此我编写了自己的公共方法,如下所示:
更新:基于给出的建议我已经审查了我的要求,因此将课程简化为如下:
public sealed class ThreadSafeList<T>
{
private readonly IList<T> list = new List<T>();
private readonly object lockable = new object();
public void Add(T t)
{
lock (lockable)
{
list.Add(t);
}
}
public IList<T> GetSnapshot()
{
IList<T> result;
lock (lockable)
{
result = new List<T>(list);
}
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
同意@jrista。您需要解决一个语义问题,为什么它被称为Translate()?意图是什么?
return new ReadOnlyCollection<T>(list);
Run Code Online (Sandbox Code Playgroud)
如果原始列表发生更改并且另一个线程正在迭代列表,您仍然会遇到线程问题。只要您意识到这一点,这就不是什么大问题。
return new List<T>(list).AsReadOnly();
Run Code Online (Sandbox Code Playgroud)
该列表没有线程问题,因为没有任何内容修改新列表。唯一的引用是由ReadOnlyCollection<T>包装器保存的。
return new List<T>(list);
Run Code Online (Sandbox Code Playgroud)
返回一个新的列表,调用者可以对其列表做他们想做的事情,而不会影响原始列表,并且对原始列表的更改不会影响此列表。
如果另一个消费者获取列表的副本然后修改他们的副本,这有什么关系吗?消费者需要看到列表的变化吗?您只需要一个线程安全的枚举器吗?
public IEnumerator<T> ThreadSafeEnumerator()
{
List<T> copy;
lock(lockable)
copy = new List<T>(list);
foreach (var value in copy)
yield return value;
}
Run Code Online (Sandbox Code Playgroud)