Как я могу выполнить неблокирующую System.Beep ()? - PullRequest
15 голосов
/ 02 мая 2010

В C # я могу выполнить Console.Beep (). Однако, если вы укажете продолжительность, скажем, 1000 или 1 секунду, он не будет выполнять следующую строку кода, пока эта секунда не пройдет.

Можно ли каким-либо образом выполнить Console.Beep () неблокирующим образом, чтобы он продолжал издавать звуковые сигналы и продолжал выполнять код, указанный ниже, во время звукового сигнала?

Ответы [ 6 ]

20 голосов
/ 02 мая 2010

Вы можете запустить его в отдельном потоке.

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

Я проснулся этим утром, чтобы найти шквал комментариев к этому ответу. Так что я решил присоединиться к другим идеям.

Вышесказанного также можно добиться, запустив поток в пуле потоков, используя следующее.

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

Важным в приведенном выше коде является вызов EndInvoke для вашего делегата, если вы используете BeginInvoke, в противном случае у вас возникнут утечки памяти.

Из MSDN: Важно : всегда вызывайте EndInvoke для завершения асинхронного вызова. http://msdn.microsoft.com/en-us/library/2e08f6yc(VS.80).aspx

В качестве альтернативы, вы можете использовать выделенный поток звуковых сигналов для запуска звуковых сигналов в фоновом режиме, когда это требуется, без создания нового потока каждый раз или с использованием пула потоков (см. Комментарий Саймона Чедвика). В качестве простого примера вы могли бы иметь следующее. Обратите внимание, что я передаю 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();
7 голосов
/ 02 мая 2010

Вы можете использовать SoundPlayer.Play () и асинхронно раздражать пользователя чем-то, что звучит лучше, чем BEEP.

6 голосов
/ 19 января 2012

Я могу что-то упустить, но почему бы не использовать:

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

Это будет воспроизводить более приятный звуковой сигнал, асинхронно, и не требует кода или служебных данных других предлагаемых решений.

4 голосов
/ 02 мая 2010

Вот дружественный к ресурсам способ воспроизвести звуковой сигнал асинхронно:

Action beep = Console.Beep;
beep.BeginInvoke(null, null); 
3 голосов
/ 02 мая 2010

Вы можете использовать следующий код для запуска Console.Beep() в другом потоке:

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

thread.Start();
1 голос
/ 02 мая 2010

Вы можете запустить Console.Beep в отдельном потоке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...