How to know when SoundPlayer has finished playing a sound

淺唱寂寞╮ 提交于 2019-12-01 07:12:50

You know, if all you want to do is play a single tone, there is Console.Beep. Granted, it doesn't do it in the background, but the technique I describe below will work fine for Console.Beep, and it prevents you having to create a memory stream just to play a tone.

In any case, SoundPlayer doesn't have the functionality that you want, but you can simulate it.

First, create your event handler:

void SoundPlayed(object sender, EventArgs e)
{
    // do whatever here
}

Change your PlayTone method so that it takes a callback function parameter:

public static void PlayTone(UInt16 frequency, int msDuration, UInt16 volume = 16383, EventHandler doneCallback = null)

Then, change the end of the method so that it calls PlaySync rather than Play, and calls the doneCallback after it's done:

using (var player = new System.Media.SoundPlayer(mStrm))
{
    player.PlaySync();
}    
if (doneCallback != null)
{
    // the callback is executed on the thread.
    doneCallback(this, new EventArgs());
}

Then, execute it in a thread or a task. For example:

var t = Task.Factory.StartNew(() => {PlayTone(100, 1000, 16383, SoundPlayed));

The primary problem with this is that the event notification occurs on the background thread. Probably the best thing to do if you need to affect the UI is to have the event handler synchronize with the UI thread. So in the SoundPlayed method, you'd call Form.Invoke (for WinForms) or Dispatcher.Invoke (WPF) to execute any UI actions.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!