2010-05-01 20 views
12

En C# puedo realizar una Console.Beep(). Sin embargo, si especifica una duración de, por ejemplo, 1000 o 1 segundo, no ejecutará la siguiente línea de código hasta que pase ese segundo.¿Cómo puedo ejecutar un System.Beep() sin bloqueo?

¿Hay alguna forma de ejecutar Console.Beep() de forma no bloqueada, por lo que continuará emitiendo un pitido y aún así continuará ejecutando el código que se encuentra debajo de él mientras se emite un pitido?

Respuesta

18

se puede ejecutar en un hilo separado.

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

Me levanté esta mañana para encontrar ráfagas de comentarios sobre esta respuesta. Así que pensé que me gustaría hablar con otras ideas.

Lo anterior también se puede lograr ejecutando el subproceso en el grupo de subprocesos, mediante el siguiente.

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

Lo importante en el código anterior es llamar EndInvoke en su delegado si utiliza BeginInvoke de lo contrario va a experimentar pérdidas de memoria.

De MSDN: Importante: llame siempre a EndInvoke para completar su llamada asincrónica. http://msdn.microsoft.com/en-us/library/2e08f6yc(VS.80).aspx

Como alternativa, puede utilizar el hilo dedicado Bip tener pitidos se ejecutan en segundo plano cuando la demanda sin crear un nuevo cada hilo o utilizando el grupo de subprocesos (ver el comentario de Simon Chadwick). Como un simple ejemplo, podrías tener lo siguiente. Tenga en cuenta que paso 1 como maxStackSize, esto garantizará que se haya comprometido el mínimo (no 1, mínimo) espacio de pila para este hilo, consulte MSDN para obtener más detalles al respecto.

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(); 
    } 
    } 

Con esto, todo lo que necesita hacer para ejecutar un pitido apaisada en cualquier momento con descarta crear nuevos temas es hacer la siguiente llamada

BackgroundBeep.Beep(); 
+1

+1 para un trazador de líneas – Earlz

+9

¡Guau, 2 MB de memoria y algunos otros recursos del sistema asignados para un pitido! –

+0

¡No convierta un hilo nuevo para ejecutar un método efímero! Esta es la mayor cantidad de patrones anti en el enhebrado que podría obtenerse. –

1

Puede ejecutar Console.Beep en un hilo separado.

3

Usted puede utilizar el código siguiente para ejecutar Console.Beep() en otro hilo:

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

thread.Start(); 
7

Usted podría utilizar SoundPlayer.Play() y asíncrona molestar al usuario con algo eso suena mejor que BEEP.

+1

+1 por molesto. – Aaronaught

4

Aquí es un amistoso manera recursos para jugar un pitido de forma asíncrona:

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

Con este método, ¿aún es posible especificar los dos parámetros int de beep? ¿Entonces puedes establecer la duración/tono? – Siracuse

+2

Acción beep =() => Console.Beep (freq, dur); beep.BeginInvoke (null, null); –

6

puedo estar perdiendo algo, pero ¿por qué no usar:

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

Esto jugará un sonido más agradable, de forma asíncrona , y no requiere el código o la sobrecarga de las otras soluciones propuestas.

+0

Me gusta este el mejor porque es corto y funciona. Gracias. – newman