2013-05-11 70 views
1

我这个代码有问题。该功能正在播放音乐曲目,因此需要一段时间才能完成执行....但是,即使通过了它,它也不会返回,直到它完成,继续执行其余的程序。我可以有功能退出,让程序继续,但音乐保持它自己的线程。欢迎任何解决方案。在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在您的UI正在运行的同一线程上执行。这就是为什么你的用户界面被阻止。

你可以开始一个新的线程这样的:

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

编辑

在要求,我添加了代码以退出线程。

+0

非常感谢,这解释了线程如何工作得更好! – 2013-05-11 21:22:10

+0

事后如何阻止胎面?现在我不能杀死它,因为线程处于静态函数。 – 2013-05-11 21:29:22

+0

这个函数是否是静态的并不重要。你应该看到一个线程是在“主进程”旁边运行的一个单独的“进程”。它们并排运行并执行各种代码(静态,非静态,创建实例等)。停止线程的最好方法是设置一个标志。我会更新我的答案。 – 2013-05-11 22:52:47

0

DirectSoundOut已经创建了自己的回放线程。完全摆脱Thread.Sleep这是阻止你的线程,只需拨打Play。订阅PlaybackStopped事件以检测播放何时完成。 audioOutput将需要是一个班级成员,所以你可以Dispose播放完成后。

+0

你能给我一个例子,我明白你的意思,但我不知道如何实现这个在我自己的代码。 – 2013-05-13 16:39:11