播放一个声音,等待它结束,然后做一些事情
本文关键字:然后 结束 等待 一个 声音 播放 | 更新日期: 2023-09-27 17:48:51
我正在编写一个Windows窗体应用程序,它应该播放三个声音文件,在每个声音文件的末尾,它将更改图像的来源。
我可以用System.Media.SoundPlayer
让它播放声音。然而,它似乎在另一个线程中播放声音,继续。
这样做的净效果是只播放最后一个声音,所有图像都发生了变化。
我试过Thread.Sleep
,但它会睡眠整个GUI,在睡眠期之后,所有事情都会同时发生,最后一个声音也会播放。
更新
我以为PlaySynch可以工作,但它似乎冻结了我的GUI,这并不理想。我还能做什么?
您尝试过SoundPlayer.PlaySync方法吗?来自帮助:
PlaySync方法使用当前线程播放.wav文件,阻止线程处理其他消息,直到加载完成。
不要使用Play方法,而是使用PlaySync方法。
使用此代码:
[DllImport("WinMM.dll")]
public static extern bool PlaySound(byte[]wfname, int fuSound);
// flag values for SoundFlags argument on PlaySound
public static int SND_SYNC = 0x0000; // Play synchronously (default).
public static int SND_ASYNC = 0x0001; // Play asynchronously.
public static int SND_NODEFAULT = 0x0002; // Silence (!default) if sound not found.
public static int SND_MEMORY = 0x0004; // PszSound points to a memory file.
public static int SND_LOOP = 0x0008; // Loop the sound until next sndPlaySound.
public static int SND_NOSTOP = 0x0010; // Don't stop any currently playing sound.
public static int SND_NOWAIT = 0x00002000; // Don't wait if the driver is busy.
public static int SND_ALIAS = 0x00010000; // Name is a registry alias.
public static int SND_ALIAS_ID = 0x00110000; // Alias is a predefined ID.
public static int SND_FILENAME = 0x00020000; // Name is file name.
public static int SND_RESOURCE = 0x00040004; // Name is resource name or atom.
public static int SND_PURGE = 0x0040; // Purge non-static events for task.
public static int SND_APPLICATION = 0x0080; // Look for application-specific association.
private Thread t; // used for pausing
private string bname;
private int soundFlags;
//-----------------------------------------------------------------
public void Play(string wfname, int SoundFlags)
{
byte[] bname = new Byte[256]; //Max path length
bname = System.Text.Encoding.ASCII.GetBytes(wfname);
this.bname = bname;
this.soundFlags = SoundFlags;
t = new Thread(play);
t.Start();
}
//-----------------------------------------------------------------
private void play()
{
PlaySound(bname, soundFlags)
}
public void StopPlay()
{
t.Stop();
}
public void Pause()
{
t.Suspend(); // Yeah, I know it's obsolete, but it works.
}
public void Resume()
{
t.Resume(); // Yeah, I know it's obsolete, but it works.
}
您可能想做的是发出异步声音,但随后禁用UI,使其不响应用户响应。然后,一旦声音播放完毕,您就可以重新启用UI。这将允许您仍然像往常一样绘制UI。
我想好了怎么做。我使用了PlaySynch,但我在一个单独的线程中播放绘制UI的代码。在播放每个文件后,同一线程还会更新UI。