C#:如何使IEnumerable <T>线程安全?

Svi*_*ish 40 c# ienumerable thread-safety

说我有这个简单的方法:

public IEnumerable<uint> GetNumbers()
{
    uint n = 0;
    while(n < 100)
        yield return n++;
}
Run Code Online (Sandbox Code Playgroud)

你会如何使这个线程安全?而且我的意思是你会得到一次枚举器,并且有多个线程处理所有数字而没有任何人得到重复.

我想在某个地方需要使用一个锁,但是哪个锁必须使迭代器块成为线程安全的呢?一般来说,如果你想要一个线程安全,你需要记住IEnumerable<T>什么?或者更确切地说,我猜这将是一个线程安全IEnumerator<T>...?

Jon*_*eet 41

这样做有一个固有的问题,因为IEnumerator<T>MoveNext()Current.你真的想要一个电话,例如:

bool TryMoveNext(out T value)
Run Code Online (Sandbox Code Playgroud)

在那一点上,你可以原子地移动到下一个元素并获得一个值.实现它并仍然可以使用yield可能是棘手的...我会考虑它.我认为你需要将"非线程安全"迭代器包装在一个原子执行的线程安全的迭代器中MoveNext()Current实现上面显示的接口.我不知道你怎么然后将这个界面包装回来,IEnumerator<T>以便你可以使用它foreach...

如果你使用的是.NET 4.0,那么Parallel Extensions 可以帮助你 - 你需要解释更多关于你想要做什么的事情.

这是一个有趣的话题 - 我可能要写博客...

编辑:我现在用两种方法写博客.

  • 你应该调用`TryMoveNext`来匹配框架中的类似项.:) (4认同)
  • @Svish:刚才博客:http://msmvps.com/blogs/jon_skeet/archive/2009/10/23/iterating-atomically.aspx (2认同)