Frage

I have a problem with this code. The function is playing a music track, so it takes a while to finish executing.... However, even through it is threaded, it does not return untill it is done, holding up the rest of the program. Can I have the function exit so that the program continues but have the music keep on it's own thread. Any solutions are welcome.

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

Thanks for the help. If you have any ideas please post.

War es hilfreich?

Lösung

Your playWav is executed on the same thread as your UI is running on. That is why your UI is blocked.

You can start a new thread like this:

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

At request, I added code to quit the thread.

Andere Tipps

DirectSoundOut already creates its own playback thread. Get rid of the Thread.Sleep altogether which is blocking your thread and simply call Play. Subscribe to the PlaybackStopped event to detect when playback has finished. The audioOutput would need to be a class member so you could Dispose it after playback had finished.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top