.net 如何使WaitHandle.WaitAny不使用较小的索引对句柄进行优先级排序?

.net 如何使WaitHandle.WaitAny不使用较小的索引对句柄进行优先级排序?,.net,multithreading,waithandle,.net,Multithreading,Waithandle,他们说: 如果在调用过程中有多个对象发出信号,则返回 值是具有最小值的有信号对象的数组索引 所有信号对象的索引值 换句话说,它不会公平地对待句柄,也就是说,选择一个信号发送时间最长的句柄是一厢情愿的想法,或者至少,只是选择一个随机信号发送的句柄,因此随着时间的推移,至少在统计上提供了公平性 当然,我可以为WaitAny提供我的等待句柄列表的不同排列,每次调用时循环或随机: public static int WaitAnyFair(this WaitHandle[] handles) {

他们说:

如果在调用过程中有多个对象发出信号,则返回 值是具有最小值的有信号对象的数组索引 所有信号对象的索引值

换句话说,它不会公平地对待句柄,也就是说,选择一个信号发送时间最长的句柄是一厢情愿的想法,或者至少,只是选择一个随机信号发送的句柄,因此随着时间的推移,至少在统计上提供了公平性

当然,我可以为WaitAny提供我的等待句柄列表的不同排列,每次调用时循环或随机:

public static int WaitAnyFair(this WaitHandle[] handles)
{
    return WaitHandle.WaitAny(Shuffle(handles));
}
但是有没有更聪明的方法呢


最初,我是在检查方法是否公平。由于它们是基于WaitHandle.WaitAny的,因此它们也不公平。

结果证明,不需要分配数组就可以轻松实现

手动调用句柄[i].WaitOne0 over i,每次以不同的迭代顺序进行。在第一次返回true的调用时中断 如果所有WaitOne调用都返回false,请执行WaitAnyhandles、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);
}

注意:我当前的用例是单线程使用者,因此我没有费心使其线程安全。

无需到第三方站点从反编译源获取.NET framework源代码,请直接转到。至于为什么它不公平,让它公平比找到第一个可用的要慢。如果我能在公平和快速之间做出选择,我宁愿选择快速作为默认值。@ScottChamberlain太棒了。我不知道消息来源也在网上。只知道下载的拉链。我在我的问题中更新了链接。今年2月左右,这种情况发生了变化。新网站提供了web界面。在WaitAny返回后,您可以检查每个句柄的状态,并在获得所有信息后决定如何继续。不确定这样做是否更明智;这听起来肯定是最慢的。@Jon它会更聪明。但是如何检查每个句柄的状态?我可以手动重置事件,但不能自动重置事件。