如果在通话过程中有多个对象发出信号,则返回 value是具有最小值的信号对象的数组索引 所有信号对象的索引值。
换句话说,它不会“公平地”处理句柄,即选择最长时间的一个信号(我猜是一厢情愿)或至少选择随机信号,以便随着时间的推移,公平至少在统计上提供。
我当然可以在每次通话时为WaitAny()
提供我的等待句柄列表(循环或随机)的不同排列:
public static int WaitAnyFair(this WaitHandle[] handles)
{
return WaitHandle.WaitAny(Shuffle(handles));
}
但是,有没有更聪明的方法呢?
(最初,我正在检查BlockingCollection.TryTakeFromAny()
方法是否合理。因为它们基于WaitHandle.WaitAny
,它们也不公平。)
答案 0 :(得分:0)
无需分配数组即可轻松实现。
handles[i].WaitOne(0)
而不是i
。在第一次调用时返回true
WaitOne()
次来电回复false
,请执行WaitAny(handles, timeout)
感谢@RaymondChen的想法。
private static int _lastWaitAnyMoreFairStartIndex;
public static int WaitAnyMoreFair(WaitHandle[] handles, TimeSpan timeout)
{
// increment, but prevent from wrapping negative,
// as that would break the modulo indexing
if (++_lastWaitAnyMoreFairStartIndex < 0)
_lastWaitAnyMoreFairStartIndex = 0;
for (int i = 0; i < handles.Length; i++)
{
var index = (i + _lastWaitAnyMoreFairStartIndex) % handles.Length;
if (handles[index].WaitOne(0))
return index;
}
return WaitHandle.WaitAny(handles, timeout);
}
N.B。我目前的用例是单线程消费者,因此我没有费心去做线程安全。