c# - 使 GetEnumerator 线程安全

标签 c# enumeration

枚举器究竟是如何工作的——我知道它们在幕后构建了一个状态机,但如果我调用 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/

相关文章:

c# - 在另一个任务中启动任务会重复我的 WebRequest

c# - 每次都强制安装

JavaScript 枚举对象 - 使用字符串或数字更快?

objective-c - 计算 id<NSFastEnumeration> 内的元素数量

c# - .net 5 Azure b2c 注销循环

c# - 使用 List<Person> Distinct() 返回 2 个值

c# - 无法将 linq 结果隐式转换为 View 模型列表

c++ - 从匿名结构访问枚举条目

ios - 挑战 : Best way to check if model object array contains properties of model in Objective-C

用于枚举的 Delphi RTTI SetValue