简体   繁体   中英

WPF - Play sound while updating UI in loop

I'm new to WPF and I finally managed to create a for loop with updating UI. But I searched many sites and didn't find a solution to my problem:

In my MainWindow I have a label

<Label x:Name="labelName" Content="{Binding LabelNameContent}"/>

and in the code-behind the Property

public string LabelNameContent
{
    get { return labelNameContent; }
    set
    {
        labelNameContent = value;
        RaisePropertyChanged("LabelNameContent");
    }
}

The text of the label gets updated in a loop and a sound should be played during the looping

Task.Factory.StartNew(() => 
{
    sound.Play();

    for(int i=0; i< 150; i++)
    {
        LabelNameContent = i.ToString();
        Thread.Sleep(500);
    }
});

My problem is, that the sound is interrupted and keeps stumbling.

How can I update the UI AND play a sound?

What class are you using to play the sound? Depending on the class, there may be an event you can register a handler with to be notified when the sound finishes playing. So you can call sound.Play , wait on an AutoResetEvent , then Set the AutoResetEvent when you receive notification that the sound finished. Finally, your loop can continue. Something like this:

At the class level in your form:

AutoResetEvent soundFinishedFlag = new AutoResetEvent(false);

Then, where you create the sound player, you would do:

sound.Finished += SoundFinished;

Note that the above line depends entirely on the sound player you're using! This is just an example!

Finally, you're anonymous function becomes:

Task.Factory.StartNew(() => 
{
    sound.Play();

    // Wait for the sound to finish playing!
    AutoResetEvent.WaitOne();  // Note that this can take an optional time out so you can limit how long your program waits, if you want to.

    for(int i = 0; i < 150; i++)
    {
        LabelNameContent = i.ToString();
        Thread.Sleep(500);
    }
});

Of course, if the sound player you're using doesn't offer an event notification that says, "I'm done", this won't help.

EDIT

Based on your response in your comment, you need to have the SoundPlayer play its sound in a thread separate from the UI & from the one updating the label's contents.

My WPF app uses SoundPlayer to play one of several different sounds. Each sound has its own dedicated SoundPlayer instance. When I play a sound, a new Thread is launched & the Play method is called on that Thread . This has the following advantages:

  1. The thread playing the sound isn't doing anything else but playing the sound.
  2. If you need to stop the sound before it's finished being played, you just stop the thread running the SoundPlayer .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM