【发布时间】:2010-12-07 01:32:05
【问题描述】:
假设我想创建一个默认线程安全的集合类。
在内部,该类有一个名为 Values 的受保护的 List<T> 属性。
对于初学者来说,让类实现ICollection<T> 是有意义的。这个接口的一些成员很容易实现;例如,Count 返回this.Values.Count。
但是实现ICollection<T> 需要我实现IEnumerable<T> 和IEnumerable(非泛型),这对于线程安全集合来说有点棘手。
当然,我总是可以在 IEnumerable<T>.GetEnumerator 和 IEnumerable.GetEnumerator 上扔一个 NotSupportedException,但这对我来说就像是逃避现实。
我已经有一个线程安全的getValues 函数,它锁定Values 并以T[] 数组的形式返回一个副本。所以我的想法是通过返回this.getValues().GetEnumerator() 来实现GetEnumerator,这样下面的代码实际上是线程安全的:
ThreadSafeCollection coll = new ThreadSafeCollection ();
// add some items to coll
foreach (T value in coll) {
// do something with value
}
不幸的是,这个实现似乎只适用于IEnumerable.GetEnumerator,而不是通用版本(因此上面的代码会抛出一个InvalidCastException)。
我的一个想法似乎可行,就是在调用GetEnumerator 之前将T[] 返回值从getValues 转换为IEnumerable<T>。另一种方法是首先将getValues 更改为返回IEnumerable<T>,然后对于非泛型IEnumerable.GetEnumerator,只需将返回值从getValues 转换为非泛型IEnumerable。但我无法确定这些方法是否草率或完全可以接受。
无论如何,有没有人对如何做这件事有更好的想法?我听说过.Synchronized 方法,但它们似乎只适用于System.Collections 命名空间中的非泛型集合。也许.NET中已经存在一个我根本不知道的通用变体?
【问题讨论】:
-
你可以使用 SynchronizedCollection... 对吧?
-
不幸的是,我们暂时被 .NET 2.0 和 VS 2005 困住了。看起来 SynchronizedCollection 在 .NET 3.0 中可用。
标签: .net collections thread-safety ienumerable ienumerator