枚举数的确切工作方式-我知道它们在后台构建了一个状态机,但是如果我两次调用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/