【问题标题】:How can I execute a non-blocking System.Beep()?如何执行非阻塞 System.Beep()?
【发布时间】:2011-02-14 15:40:06
【问题描述】:

在 C# 中,我可以执行 Console.Beep()。但是,如果您指定 1000 或 1 秒的持续时间,则在该秒过去之前它不会执行下一行代码。

有什么方法可以以非阻塞方式执行 Console.Beep(),这样它会继续发出哔哔声并在哔哔声时继续执行它下面的代码?

【问题讨论】:

    标签: c# .net console


    【解决方案1】:

    您可以在单独的线程中运行它。

    new Thread(() => Console.Beep()).Start();
    

    我今天早上醒来发现这个答案一连串的 cmets。所以我想我会提出一些其他的想法。

    上面也可以实现在线程池上运行线程,使用下面的方法。

    Action beep = Console.Beep;
    beep.BeginInvoke((a) => { beep.EndInvoke(a); }, null);
    

    上述代码中重要的是,如果您使用 BeginInvoke,则在您的委托上调用 EndInvoke,否则您将遇到内存泄漏。

    来自 MSDN:重要提示:始终调用 EndInvoke 来完成您的异步调用。 http://msdn.microsoft.com/en-us/library/2e08f6yc(VS.80).aspx

    或者,您可以使用专用的 Beep 线程在需要时在后台运行哔声,而无需每次都创建新线程或使用线程池(请参阅 Simon Chadwick 的评论)。作为一个简单的示例,您可以拥有以下内容。请注意,我将 1 作为 maxStackSize 传递,这将确保为此线程提交最小(不是 1,最小)堆栈空间,有关此的更多详细信息,请参阅 MSDN。

      class BackgroundBeep
      {
        static Thread _beepThread;
        static AutoResetEvent _signalBeep;
    
        static BackgroundBeep()
        {
          _signalBeep = new AutoResetEvent(false);
          _beepThread = new Thread(() =>
              {
                for (; ; )
                {
                  _signalBeep.WaitOne();
                  Console.Beep();
                }
              }, 1);
          _beepThread.IsBackground = true;
          _beepThread.Start();      
        }
    
        public static void Beep()
        {
          _signalBeep.Set();
        }
      }
    

    有了这个,你需要做的就是在不创建新线程的情况下随时运行背景蜂鸣声

    BackgroundBeep.Beep();
    

    【讨论】:

    • 哇,2MB+ 的内存和一些其他系统资源分配给了哔声!
    • @Pop Catalin:你有启动线程时内存开销的链接/参考吗?
    • 如果应用程序需要这个(可能还有其他)非阻塞功能,那么您可以在应用程序启动时创建一个专用线程,并让它在信号量上等待。当应用程序需要哔声时,它所要做的就是提高信号量。这样就不会为每个哔声创建一个新线程。此外,这个后台线程可以等待“命令”对象的队列,因此它可以执行许多不同的操作。在这种情况下,应用程序会将“Beep, 1000, 200”命令推送到队列中,后台线程会将其从队列中弹出并执行操作。
    • @Eric,堆栈页面由 CLR 提交,而不仅仅是保留。乔达菲的帖子:bluebytesoftware.com/blog/2007/03/10/…
    • 嗯,我今天学到了一些新的东西——而且令人惊讶。我不知道我们会做这种疯狂的事情来提交所有的记忆。奇怪!
    【解决方案2】:

    您可以使用 SoundPlayer.Play() 并异步地用听起来比 BEEP 更好的东西来惹恼用户。

    【讨论】:

      【解决方案3】:

      我可能遗漏了一些东西,但为什么不使用:

      System.Media.SystemSounds.Beep.Play();
      

      这将异步播放更好的哔声,并且不需要其他建议解决方案的代码或开销。

      【讨论】:

        【解决方案4】:

        这是一种资源友好异步播放哔声的方法:

        Action beep = Console.Beep;
        beep.BeginInvoke(null, null); 
        

        【讨论】:

        • 用这个方法,还能指定beep的两个int参数吗?所以你可以设置持续时间/音高?
        • 动作蜂鸣 = () => Console.Beep(freq, dur); beep.BeginInvoke(null, null);
        【解决方案5】:

        您可以使用以下代码在另一个线程中运行Console.Beep()

        System.Threading.Thread thread = new System.Threading.Thread(
            new System.Threading.ThreadStart(
                delegate()
                {
                    Console.Beep();
                }
            ));
        
        thread.Start();
        

        【讨论】:

          【解决方案6】:

          您可以在单独的线程中运行Console.Beep

          【讨论】:

            【解决方案7】:

            非常简单!

            Task.Run(() => Console.Beep(440, 1000));
            

            或者,如果您处于异步环境中:

            await Task.Run(() => Console.Beep(440, 1000));
            

            https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.run?view=net-5.0#System_Threading_Tasks_Task_Run_System_Action_

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-05-29
              • 1970-01-01
              • 2019-11-16
              • 2023-04-08
              • 1970-01-01
              相关资源
              最近更新 更多