并发集合枚举器

时间:2018-03-12 09:52:08

标签: c# .net

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

我的排序列表的内部表示基本上是与head的链接列表和链接在一起的插槽。 类似的东西:

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

    public Slot(T value, Slot next = null)
    {
        Value = value;
        Next = next;
    }
}

每次我使用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;
        }
    }
}

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

1 个答案:

答案 0 :(得分:1)

感谢各位评论,总结一下。

答案:是的,syncLock将被锁定一段时间→因此,这是一个非常糟糕的主意

可能的解决方案:

  • 使收集不是线程安全的
  • 获取锁定,复制整个集合并返回此集合的枚举器@Evk
  • 使用某种布尔标志,在true上设置它,同时枚举集合并在调用AddClearRemove方法时抛出异常 - &gt;这是默认的List行为@ManfredRadlwimmer
  • 使该集合不可变@InBetween