是否可以重构此 EventWaitHandle 以不使用 Thread.Sleep() 来控制竞争条件?

Posted

技术标签:

【中文标题】是否可以重构此 EventWaitHandle 以不使用 Thread.Sleep() 来控制竞争条件?【英文标题】:Is it possible to refactor this EventWaitHandle to not use Thread.Sleep() to control the race condition? 【发布时间】:2012-02-17 21:36:43 【问题描述】:

我想从服务器向所有客户端发送消息。有 0-* 个客户。加载客户端时,服务器可能正在运行,也可能不运行。这里的功能按我的意愿工作。我想弄清楚这是否可以在没有Thread.Sleep() 的情况下完成?另请注意,客户端和服务器各自处于独立进程中。

服务器部分

class NamedEventsServer

    internal static void Main()
    
        const string ewhName = "StickyNoteEwh";

        EventWaitHandle ewh = null;
        bool doesNotExist = false;
        bool wasCreated;

        // Attempt to open the named event.
        try
        
            ewh = EventWaitHandle.OpenExisting(ewhName);
        
        catch (WaitHandleCannotBeOpenedException)
        
            Console.WriteLine("Named event does not exist.");
            doesNotExist = true;
        
        if (doesNotExist)
        
            // The event does not exist, so create it.

            ewh = new EventWaitHandle(true,
                EventResetMode.ManualReset,
                ewhName,
                out wasCreated);

            if (wasCreated)
            
                Console.WriteLine("Created the named event.");
            
            else
            
                Console.WriteLine("Unable to create the event.");
                return;
            
        
        ewh.Set();
        Thread.Sleep(1000);//wait one second...giving threads enough time to all respond.  Then stop triggering the event.
        ewh.Reset();

        //exit
    

客户端部分

class NamedEventsClient

    internal static void Main()
    
        const string ewhName = "StickyNoteEwh";

        while (true)
        
            EventWaitHandle ewh = null;
            bool doesNotExist = false;
            bool wasCreated;
            // Attempt to open the named event.
            try
            
                ewh = EventWaitHandle.OpenExisting(ewhName);
            
            catch (WaitHandleCannotBeOpenedException)
            
                Console.WriteLine("Named event does not exist.");
                doesNotExist = true;
            
            if (doesNotExist)
            
                // The event does not exist, so create it.

                ewh = new EventWaitHandle(false,
                    EventResetMode.ManualReset,
                    ewhName,
                    out wasCreated);

                if (wasCreated)
                
                    Console.WriteLine("Created the named event.");
                
                else
                
                    Console.WriteLine("Unable to create the event.");
                    return;
                
            
            Console.WriteLine("Wait on the event.");
            ewh.WaitOne();
            Console.WriteLine("Event was signaled.");
            //Console.WriteLine("Press the Enter key exit.");
            Thread.Sleep(1000);
            //Console.ReadLine();
        
    

【问题讨论】:

【参考方案1】:

我想这取决于您是否确定所有客户都会在第二秒内获得他们的时间片。这听起来很合理,但在极度压力下,一些客户可能会错过它。这有多重要?

无论如何,我认为这正是您应该使用 ZeroMQ 的事情。它重量轻,可以为您解决所有潜在的错误。

【讨论】:

以上是关于是否可以重构此 EventWaitHandle 以不使用 Thread.Sleep() 来控制竞争条件?的主要内容,如果未能解决你的问题,请参考以下文章

我需要 Dispose() 或 Close() EventWaitHandle 吗?

EventWaitHandle

等到 EventWaitHandle.Set() 之后通知所有进程

重构此代码以更好地利用 CSharpFunctionalExtensions 库

.NET EventWaitHandle 慢

使用 EventWaitHandle 类