枚举数的确切工作方式-我知道它们在后台构建了一个状态机,但是如果我两次调用GetEnumerator,我会得到两个不同的对象吗?

如果我做这样的事情

  public IEnumerator<T> GetEnumerator()
  {
     yield return 1;
     yield return 2;
  }

我可以在方法开始时获取一个锁吗,这个锁是否一直保持到枚举器返回null或枚举器被GC为止?

如果调用方重置枚举器等会发生什么?

我想我的问题是与枚举器打交道时管理锁定的最佳方法是什么

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

最后,上面的示例是问题的简化-yield语句的作用要比我所显示的要多:)

最佳答案

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

您可以在迭代器块中获取一个锁,但是要注意,直到调用者第一次调用MoveNext()之前,方法中的任何代码都不会被调用。

通常,我建议尽可能不要在迭代器块中持有锁。您不知道在调用MoveNext()之间调用者将要做什么。只要他们在某个时候处理了迭代器,该锁最终就会被释放,但这仍然意味着您受调用者的摆布。

如果您可以向我们提供有关您要执行的操作的更多信息,那将会有所帮助。一种可能更容易正确实现的替代设计是:

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

关于c# - 使GetEnumerator成为ThreadSafe,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5926448/

10-10 11:42