C#中的基本锁定问题

Had*_*adi 0 .net c# multithreading locking thread-safety

课程:

public class SomeCollection
{
    public void IteratorReset()
    {
      index = -1;
    }

    public bool IteratorNext()
    {
      index++;
      return index < Count;
    }

    public int Count
    {
      get
      {
          return floatCollection.Count;
      }
    }

    public float CurrentValue
    {
      get
      {
        return floatCollection[index];
      }
    }

    public int CurrentIndex
    {
      get
      {
        return intCollection[index];
      }
    }
}
Run Code Online (Sandbox Code Playgroud)

包含对"SomeCollection"的引用的类:

public class ThreadUnsafeClass
{    
    public SomeCollection CollectionObj
    {
       get
       {
           return collectionObj;
        }               
    }      
}
Run Code Online (Sandbox Code Playgroud)

ClassA,ClassBClassC包含迭代CollectionObj的以下循环:

for (threadUnsafeClass.CollectionObj.IteratorReset(); threadUnsafeClass.CollectionObj.IteratorNext(); )
{
    int currentIntIndex = threadUnsafeClass.CollectionObj.CurrentIndex;
    float currentfloatValue = threadUnsafeClass.CollectionObj.CurrentValue;

    // ...    
}
Run Code Online (Sandbox Code Playgroud)

因为我只在3个类中读取 CollectionObj,所以我使用多线程来加速,但我不太确定如何强制执行线程安全.我在检索CollectionObj时在ThreadUnsafeClass中添加了一个锁,但是应用程序抛出了超出范围的异常.

任何帮助表示赞赏.

谢谢 !

Jon*_*eet 5

您只是阅读该CollectionObj属性,但随后您正在改变该值所引用的对象.看到这一点:

for (threadUnsafeClass.CollectionObj.IteratorReset(); 
     threadUnsafeClass.CollectionObj.IteratorNext(); )
Run Code Online (Sandbox Code Playgroud)

双方IteratorResetIteratorNext发生变异SomeCollection改变的值index.基本上,您无法使用当前代码安全地执行此操作.例如,几个线程可以同时调用IteratorNext().第一个调用返回true,但在该线程有机会读取值之前,其他线程使索引无效.

为什么使用集合本身进行迭代?通常你会实现IEnumerable<T>,并返回一个新的对象GetEnumerator.这样,不同的线程可以各自获得在同一集合上表示"他们的"光标的不同对象.他们都可以迭代它,所有人都看到了所有的价值观.