我正在编写自己的优先级队列/排序列表的实现,我想让它并发.为了让它的线程安全我正在使用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在枚举器中一直被锁定(因此它会在到达方法结束后解锁)或者在产生值后自动解锁?
谢谢大家的评论,总结如下。
\n\n答案:是的,syncLock将一直被锁定 \xe2\x86\x92 因此,这是一个非常糟糕的主意
可能的解决方案:
\n\ntrue在枚举集合时将其设置为打开状态Add,并在调用Clear或Remove方法时抛出异常 -> 这是默认List行为@ManfredRadlwimmer