并发集合枚举器

Luk*_*s F 7 .net c#

我正在编写自己的优先级队列/排序列表的实现,我想让它并发.为了让它的线程安全我正在使用lock(someObject),我想验证C#中的互斥体的一些行为.

我的排序列表的内部表示基本上是链接列表head和链接在一起的插槽.就像是:

internal class Slot
{
    internal T Value;
    internal Slot Next;

    public Slot(T value, Slot next = null)
    {
        Value = value;
        Next = next;
    }
}
Run Code Online (Sandbox Code Playgroud)

每次我操作head都必须使用lock(someObject)因为线程安全.为了实现ICollection我必须实现的接口public IEnumerator<T> GetEnumerator().在这种方法中,我接受了我的head阅读,因此我应该使用互斥量.

public IEnumerator<T> GetEnumerator()
{
    lock (syncLock)
    {
        var curr = head;
        while (curr != null)
        {
            yield return curr.Value;
            curr = curr.Next;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:syncLock在枚举器中一直被锁定(因此它会在到达方法结束后解锁)或者在产生值后自动解锁?

Luk*_*s F 1

谢谢大家的评论,总结如下。

\n\n

答案:是的,syncLock将一直被锁定 \xe2\x86\x92 因此,这是一个非常糟糕的主意

\n\n

可能的解决方案:

\n\n
    \n
  • 使集合不是线程安全的
  • \n
  • 获取锁,复制整个集合并返回该集合的枚举器@Evk
  • \n
  • 使用某种布尔标志,true在枚举集合时将其设置为打开状态Add,并在调用ClearRemove方法时抛出异常 -> 这是默认List行为@ManfredRadlwimmer
  • \n
  • 使该集合不可变@InBetween
  • \n
\n