如果我们查看源代码,我们会发现GetEnumerator也是线程安全的,因此我认为A和B都是线程安全的。
当您调用.ToList()时,Linq会调用List的构造函数。
public List(IEnumerable<T> collection) {
所以这段代码实际上是创建了一个类似于线程安全的副本:
using(IEnumerator<T> en = collection.GetEnumerator()) {
while(en.MoveNext()) {
Add(en.Current);
}
ConcurrentQueue的源代码
List的源代码
public IEnumerator<T> GetEnumerator()
{
Interlocked.Increment(ref m_numSnapshotTakers);
Segment head, tail;
int headLow, tailHigh;
GetHeadTailPositions(out head, out tail, out headLow, out tailHigh);
return GetEnumerator(head, tail, headLow, tailHigh);
}
调查员的备注还提到了我们可以同时使用它:
/// The enumeration represents a moment-in-time snapshot of the contents
/// of the queue. It does not reflect any updates to the collection after
/// <see cref="GetEnumerator"/> was called. The enumerator is safe to use
/// concurrently with reads from and writes to the queue.
.ToList()
上,它是作为队列的实例方法显示,还是作为 Enumerable 的扩展方法显示? - Lasse V. Karlsen