我的代码有问题。该功能正在播放音乐曲目,因此需要一段时间才能完成执行....但是,即使它是有线程的,它也不会返回,直到它完成,占用了程序的其余部分。我可以让函数退出,以便程序继续,但让音乐保持在它自己的线程上。欢迎任何解决方案。
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();
}
}
}
感谢您的帮助。如果您有任何想法,请发布。
答案 0 :(得分:4)
您的playWav
在运行UI的同一个线程上执行。这就是您的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();
}
}
编辑
根据要求,我添加了退出线程的代码。
答案 1 :(得分:0)
DirectSoundOut
已经创建了自己的播放线程。完全删除阻止你的线程的Thread.Sleep
并简单地调用Play
。订阅PlaybackStopped
事件以检测播放何时结束。 audioOutput
需要是一个班级成员,因此您可以在播放结束后Dispose
。