代码之家  ›  专栏  ›  技术社区  ›  TacticalMin

waitany(Array)实际上是“设置”了一个事件,还是只是返回一个有信号的事件的索引

  •  2
  • TacticalMin  · 技术社区  · 11 年前

    http://msdn.microsoft.com/en-us/library/tdykks7z.aspx

    根据文档,返回值为:

    “满足等待的对象的数组索引。”

    因此,这意味着索引表示已设置的事件,并且此代码将导致死锁,因为它将等待自己:

        private static AutoResetEvent waitLock()
        {
            //Wait for any of the events to be signaled 
            AutoResetEvent autoEvent;
            lock(yahooRequests)    //Note: yahoo requests is a array of auto reset events
            {
                int index = AutoResetEvent.WaitAny(yahooRequests);
                autoEvent = yahooRequests[index];
                autoEvent.WaitOne();
            }
            return autoEvent;
        }
    

    这个代码是正确的:

    private static AutoResetEvent waitLock()
    {
        //waitany returns the index of a successfull wait. So this line returns the reference to a autoresetevent.
        return yahooRequests[AutoResetEvent.WaitAny(yahooRequests)];
    }
    

    我只是想确保(在我看来)文件不是100%清楚

    编辑:

    我的设计有缺陷——正如@Hans Passant所指出的那样,我本应该使用信号灯。因为我想确保有N个yahooRequest可以访问一个函数。但@arno从技术上回答了最初的问题。真希望我能设置两个可接受的asnwer

    编辑:

    正如@Sriram Sakthvel在评论中指出的那样,第一个例子将永远等待自己。但实际上并不是僵局。

    2 回复  |  直到 11 年前
        1
  •  3
  •   Arno    11 年前

    这个 WaitHandle.WaitAny 方法确实如此 设置事件。它返回 满足等待的对象的数组索引。 这可能需要等待,或者在调用之前设置事件时也可能发生 WaitAny 完成。在后一种情况下,索引将在不等待的情况下返回。

        2
  •  2
  •   Hans Passant    11 年前

    这意味着索引表示一个已等待的事件

    不,数组中的所有事件都已等待。返回的索引只是第一个Set()。它将在WaitAny()返回后重置。因此,第一个片段确实毫无意义,您不想再次调用WaitOne()。第二个片段没有多大意义,您返回的AutoResetEvent对象没有任何区别。特别是,由于ARE自动复位,因此不再发出信号。你真的需要知道索引才能知道哪项工作完成了。