2010-05-01 15 views
12

In C# È possibile eseguire un Console.Beep(). Tuttavia, se si specifica una durata di dire 1000 o 1 secondo, non eseguirà la riga di codice successiva fino a quando non trascorrerà il secondo.Come posso eseguire un System.Beep() non bloccante?

Esiste un modo per eseguire Console.Beep() in modo non bloccante, quindi continuerà a emettere un segnale acustico e continuerà a eseguire il codice al di sotto di esso mentre emette un segnale acustico?

risposta

18

è possibile eseguirlo in un thread separato.

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

Mi sono svegliato questa mattina per trovare confusione di commenti su questa risposta. Quindi ho pensato di inserire altre idee.

È possibile ottenere quanto sopra anche eseguendo il thread sul Pool di thread, utilizzando quanto segue.

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

La cosa importante nel codice sopra è di chiamare EndInvoke sul vostro delegato, se si utilizza BeginInvoke altrimenti si sperimenterà perdite di memoria.

Da MSDN: Importante: chiamare sempre EndInvoke per completare la chiamata asincrona. http://msdn.microsoft.com/en-us/library/2e08f6yc(VS.80).aspx

In alternativa, è possibile utilizzare il filo Beep dedicato ad avere segnali acustici eseguiti in background quando su richiesta senza creare una nuova ogni filo o utilizzando il pool di thread (si veda il commento di Simon Chadwick). Come un semplice esempio, potresti avere il seguente. Notare che io passo 1 come maxStackSize, questo garantirà che lo spazio minimo (non 1, minimo) dello stack sia impegnato per questo thread, vedere MSDN per maggiori dettagli su questo.

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 questo, tutto quello che dovete fare per eseguire un segnale acustico backround in qualsiasi momento con fuori la creazione di nuove discussioni è effettuare la seguente chiamata

BackgroundBeep.Beep(); 
+1

+1 per un liner – Earlz

+9

Wow, 2 MB di memoria e altre risorse di sistema allocate per un segnale acustico! –

+0

Si prega di non girare una nuova discussione per eseguire un metodo di breve durata! Questo è il maggior numero di pattern anti nel threading che potrebbero ottenere. –

1

È possibile eseguire Console.Beep in una discussione separata.

3

È possibile utilizzare il seguente codice per eseguire Console.Beep() in un altro thread:

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

thread.Start(); 
7

Si potrebbe utilizzare SoundPlayer.Play() e in modo asincrono infastidire l'utente con qualcosa sembra migliore del BEEP.

+1

+1 per fastidiosi. – Aaronaught

4

Ecco un risorsa amichevole modo per giocare un segnale acustico in modo asincrono:

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

Con questo metodo, è ancora possibile specificare i due parametri int di beep? Quindi puoi impostare durata/altezza? – Siracuse

+2

Azione beep =() => Console.Beep (freq, dur); beep.BeginInvoke (null, null); –

6

io possa mancare qualcosa, ma perché non usare:

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

Questo avrà un segnale acustico più bello, in modo asincrono e non richiede il codice o il sovraccarico delle altre soluzioni proposte.

+0

Mi piace questo il migliore perché è corto e funziona. Grazie. – newman