制作GetEnumerator ThreadSafe

Jac*_*ada 5 c# enumeration

枚举器究竟是如何工作的 - 我知道他们在幕后构建了一个状态机,但如果我两次调用GetEnumerator,我会得到两个不同的对象吗?

如果我做这样的事情

  public IEnumerator<T> GetEnumerator()
  {
     yield return 1;
     yield return 2;
  }
Run Code Online (Sandbox Code Playgroud)

我可以在方法的开头获取一个锁,并且这个锁一直保持到枚举器返回null或者直到枚举器是GC的?

如果调用者重置枚举器等会发生什么 -

我想我的问题是在处理枚举器时管理锁定的最佳方法是什么

注意:客户端不能负责线程同步 - 内部需要的类

最后上面的例子是问题的简化 - yield语句比我显示的更多:)

Jon*_*eet 9

是的,每次调用您的GetEnumerator()方法都会创建一个不同的对象(一个新的状态机).

可以在迭代器块中获取锁,但请注意,在调用者MoveNext()第一次调用之前,不会调用方法中的任何代码.

一般来说,如果可能的话,我建议不要在迭代器块持有一个锁.你不知道调用之间调用者会做什么MoveNext().只要他们在某个时刻处理迭代器,锁定将最终释放,但它仍然意味着你受到调用者的支配.

如果您可以向我们提供有关您尝试做的更多信息,那将有所帮助.另一种可能更容易实现的设计是:

public void DoSomething(Action<T> action)
{
    lock (...)
    {
        // Call action on each element in here
    }
}
Run Code Online (Sandbox Code Playgroud)