枚举器究竟是如何工作的——我知道它们在幕后构建了一个状态机,但如果我调用 GetEnumerator 两次,我会得到两个不同的对象吗?
如果我这样做
public IEnumerator<T> GetEnumerator()
{
yield return 1;
yield return 2;
}
我能否在方法开始时获取一个锁,这个锁是否一直持有到枚举器返回 null 或枚举器被 GC 处理为止?
如果调用者重置枚举器等会发生什么 -
我想我的问题是在处理枚举器时管理锁定的最佳方式是什么
注意:客户端不能负责线程同步——类内部需要
最后,上面的示例是问题的简化 - yield 语句比我展示的要多一些:)
最佳答案
是的,每次调用您的 GetEnumerator()
方法都会创建一个不同的对象(一个新的状态机)。
您可以获取迭代器 block 中的锁,但请注意,在调用者为第一次。
一般来说,如果可能的话,我会建议反对在迭代器 block 中持有锁。您不知道调用者在两次调用 MoveNext()
之间要做什么。只要他们在某个时候处理迭代器,锁最终就会被释放,但这仍然意味着你任由调用者摆布。
如果您能向我们提供更多关于您正在尝试做什么的信息,那将会有所帮助。另一种可能更容易正确的设计是:
public void DoSomething(Action<T> action)
{
lock (...)
{
// Call action on each element in here
}
}
关于c# - 使 GetEnumerator 线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5926448/