如何执行非阻塞System.Beep()?

Sir*_*use 15 .net c# console

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

有没有办法以非阻塞的方式执行Console.Beep(),这样它会继续发出蜂鸣声并仍然继续执行下面的代码同时发出哔哔声?

Chr*_*lor 20

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

new Thread(() => Console.Beep()).Start();
Run Code Online (Sandbox Code Playgroud)

我今天早上醒来发现对这个答案的一连串评论.所以我想我会想到其他一些想法.

通过使用以下内容,也可以通过线程池上的线程来实现上述操作.

Action beep = Console.Beep;
beep.BeginInvoke((a) => { beep.EndInvoke(a); }, null);
Run Code Online (Sandbox Code Playgroud)

上面代码中的重要一点是,如果使用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();
    }
  }
Run Code Online (Sandbox Code Playgroud)

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

BackgroundBeep.Beep();
Run Code Online (Sandbox Code Playgroud)

  • 哇,2MB +的内存和一些其他系统资源分配给一个嘟嘟声! (9认同)
  • 如果应用程序需要此(可能还有其他)非阻塞函数,那么您可以在应用程序启动时创建专用线程,并让它等待信号量.当应用程序需要发出蜂鸣声时,它所要做的就是提高信号量.这样,不会为每个蜂鸣声创建新线程.此外,此后台线程可以在"命令"对象的队列上等待,因此它可以执行许多不同的操作.在这种情况下,应用程序会将"Beep,1000,200"命令推送到队列中,后台线程会将其从队列中弹出并执行操作. (5认同)
  • @Eric,堆栈页面由CLR提交,而不仅仅是保留.Joe Duffy的帖子:http://www.bluebytesoftware.com/blog/2007/03/10/TheCLRCommitsTheWholeStack.aspx (5认同)
  • 那么今天我学到了一些新的东西 - 而且令人惊讶.我不知道我们会做这个疯狂的事情,承诺所有的记忆.奇怪的! (4认同)
  • @Pop Catalin:启动线程时是否有内存开销的链接/参考? (2认同)
  • @Pop:您显然有一些信念,即为128个8KB页面的虚拟地址空间设置"此页保留"位真的非常昂贵.为什么设置128位真的很贵?究竟你认为保留一百万字节的虚拟地址空间需要什么?记住,这不是物理内存,这是*表格中的*注释,如果您需要它们,页面将在VIRTUAL地址空间中的位置*.它们在被使用之前不会被映射到物理内存中,并且它们从未被使用过.你能解释为什么你认为这是一种稀缺资源吗? (2认同)

Han*_*ant 7

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


Cam*_*ers 6

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

System.Media.SystemSounds.Beep.Play();
Run Code Online (Sandbox Code Playgroud)

这将以异步方式发出更好的蜂鸣声,并且不需要其他提议的解决方案的代码或开销.