2013-05-11 3 views
1

У меня проблема с этим кодом. Функция воспроизводит музыкальную дорожку, поэтому для завершения выполнения требуется некоторое время ... Однако даже через нее пронумеровано, оно не возвращается до тех пор, пока оно не будет выполнено, удерживая остальную часть программы. Могу ли я запустить функцию, чтобы программа продолжалась, но музыка сохранялась в ее собственном потоке. Любые решения приветствуются.Threading a function in C# не работает

using System; 
using Gtk; 
using NAudio; 
using NAudio.Wave; 
using System.Threading; 

public class Trackbox { 

    public static void Main() { 
     Application.Init(); 

     //Create the Window 
     Window myWin = new Window("Trackbox"); 
     myWin.SetIconFromFile("Assets//logo.png"); 
     myWin.Resize(200, 100); 


     //Add the label to the form  
     //myWin.Add(myLabel); 

     Button playButton = new Button("Play Sound"); 
     //This when playwav is called here, the rest of the application waits for it to finish playing 

     playButton.Clicked += new EventHandler(playWav); 
     myWin.Add(playButton); 

     myWin.DeleteEvent += delegate { Application.Quit(); }; 
     //Show Everything  
     myWin.ShowAll(); 


     Application.Run(); 


    } 

    private static void playWav(object sender, EventArgs e) 
    { 
     var soundFile = @"C:\sound.wav"; 
     using (var wfr = new WaveFileReader(soundFile)) 
     using (WaveChannel32 wc = new WaveChannel32(wfr) { PadWithZeroes = false }) 
     using (var audioOutput = new DirectSoundOut()) 
     { 
      audioOutput.Init(wc); 

      audioOutput.Play(); 

      while (audioOutput.PlaybackState != PlaybackState.Stopped) 
      { 
       Thread.Sleep(20); 
      } 

      audioOutput.Stop(); 
     } 
    } 
} 

Спасибо за помощь. Если у вас есть идеи, напишите.

ответ

4

Ваш playWav выполнен в той же теме, что и ваш пользовательский интерфейс. Вот почему ваш интерфейс заблокирован.

Вы можете начать новую тему, как это:

private volatile bool _QuitThread; 

private void playWav(object sender, EventArgs e) 
{ 
    _QuitThread = false; 
    Thread thread = new Thread(playWavThread); 
    thread.Start(); 
} 

// This method should be called when the music should stop. Perhapse when a button has been pressed. 
private void StopTheMusic() 
{ 
    _QuitThread = true; 
} 

private void playWavThread() 
{ 
    var soundFile = @"C:\sound.wav"; 
    using (var wfr = new WaveFileReader(soundFile)) 
    using (WaveChannel32 wc = new WaveChannel32(wfr) { PadWithZeroes = false }) 
    using (var audioOutput = new DirectSoundOut()) 
    { 
     audioOutput.Init(wc); 
     audioOutput.Play(); 
     while (!_QuitThread && audioOutput.PlaybackState != PlaybackState.Stopped) 
     { 
      Thread.Sleep(20); 
     } 
     audioOutput.Stop(); 
    } 
} 

EDIT

По желанию, я добавил код, чтобы выйти из потока.

+0

Большое вам спасибо, это объясняет, как поток работает намного лучше! –

+0

Как остановить протекцию после факта? Прямо сейчас я не могу убить его, потому что поток находится в статической функции. –

+0

Не имеет значения, является ли эта функция статической или нет. Вы должны увидеть поток как отдельный «процесс», выполняющийся рядом с «основным процессом». Они работают бок о бок и выполняют все виды кода (статика, не статика, создание экземпляров и т. Д.). Лучший способ остановить поток - установить флаг. Я уточню свой ответ. –

0

DirectSoundOut уже создает свою собственную нить воспроизведения. Избавьтесь от Thread.Sleep вообще, который блокирует вашу нить и просто звонит Play. Подпишитесь на событие PlaybackStopped, чтобы определить, когда воспроизведение закончено. audioOutput должен быть членом класса, чтобы вы могли Dispose после завершения воспроизведения.

+0

Не могли бы вы привести мне пример, я получаю то, что вы говорите, но не уверен, как реализовать это в моем собственном коде. –