播放声音,等待它完成然后做点啥?
Posted
技术标签:
【中文标题】播放声音,等待它完成然后做点啥?【英文标题】:Play a sound, wait for it to finish and then do something?播放声音,等待它完成然后做点什么? 【发布时间】:2010-09-14 00:04:15 【问题描述】:我正在编写一个Windows Forms 应用程序,它应该播放三个声音文件,并且在每个声音文件的末尾,它是更改图像的来源。
我可以让它使用System.Media.SoundPlayer
播放声音。但是,它似乎在另一个线程中播放声音,继续播放。
这样做的最终效果是只播放最后一个声音,而所有图像都改变了。
我尝试过Thread.Sleep
,但它使整个 GUI 处于休眠状态,并且在休眠期之后,一切都立即发生,它播放的最后一个声音。
更新
我认为 PlaySynch 可以正常工作,但它似乎冻结了我的 GUI,这并不理想。我还能做什么?
【问题讨论】:
【参考方案1】:你试过SoundPlayer.PlaySync Method吗?来自帮助:
PlaySync 方法使用当前 线程播放 .wav 文件,防止 从处理其他线程 消息直到加载完成。
【讨论】:
是的,我刚刚发现了这个,唯一的问题是 Gui 似乎没有被绘制出来......会继续努力。【参考方案2】:不要使用 Play 方法,而是使用 PlaySync 方法。
【讨论】:
【参考方案3】:使用此代码:
[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.
【讨论】:
我认为这太过分了。【参考方案4】:您可能想要做的是做一个异步声音,然后以不响应用户响应的方式禁用您的 UI。然后,一旦播放了声音,您就可以重新启用您的 UI。这将允许您照常绘制 UI。
【讨论】:
【参考方案5】:我想出了怎么做。我使用了 PlaySynch,但我在一个单独的线程中对绘制 UI 的代码进行了播放。播放每个文件后,同一线程也会更新 UI。
【讨论】:
以上是关于播放声音,等待它完成然后做点啥?的主要内容,如果未能解决你的问题,请参考以下文章