5

回到 .NET Reflector 是免费的时候,我用它来喘口气进入 .NET 框架代码。我注意到 .NET 2.0 中的大多数集合(我相信这也适用于当前版本)使用以下机制来识别循环期间的集合修改:

public class SomeCollection<T>
{
    internal int version = 0;

    // code skipped for brevity

    public void Add(T item)
    {
        version++;

        // add item logic ...
    }

    public IEnumerator<T> GetEnumerator()
    {
         return new SomeCollectionEnumerator<T>(this);
    }
}

public class SomeCollectionEnumerator<T> : IEnumerator<T>
{
     private SomeCollection<T> collection;
     private int version;

     public SomeCollectionEnumerator(SomeCollection<T> collection)
     {
         this.version = collection.version;
         this.collection = collection;
     }

     public bool MoveNext()
     {
         if (this.version != this.collection.version)
         {
             // collection was modified while iterated over
             throw SomeException(...);
         }
         // iteration logic here...
     }
}

现在想象一个长时间运行的应用程序(一个频繁使用的 Web 服务,必须有最少的停机时间并且应该是稳定和可靠的)的假设情况,它将给定的集合实例(.NET 框架中的内置集合类型之一)保存在内存中只要它运行。集合被频繁地修改,以便int.MaxValue可能发生修改。集合的每个修改方法中的行是否存在引发溢出异常的风险version++(假设溢出检查未全局禁用)。

我必须承认我对反射代码的细节记忆很差,但我不记得操作unckecked周围的块的用法version++。这是否意味着.NET 中的内置集合类型不适合这种长时间运行的应用场景?只是出于好奇,有人遇到过这种情况可能发生的现实场景吗?

4

1 回答 1

4

不,因为 c# 编译器默认不选中整数算术。(这包括编译的 BCL。)

于 2012-08-11T22:08:28.090 回答