在c#中线程化函数不起作用

时间:2013-05-11 20:07:21

标签: c# multithreading gtk# naudio

我的代码有问题。该功能正在播放音乐曲目,因此需要一段时间才能完成执行....但是,即使它是有线程的,它也不会返回,直到它完成,占用了程序的其余部分。我可以让函数退出,以便程序继续,但让音乐保持在它自己的线程上。欢迎任何解决方案。

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

感谢您的帮助。如果您有任何想法,请发布。

2 个答案:

答案 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