C# 播放一个声音,等待它完成然后做点什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/148676/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 15:36:57  来源:igfitidea点击:

Play a sound, wait for it to finish and then do something?

提问by Omar Kooheji

I'm writing a Windows Formsapplication which is supposed to play three sound files and at the end of each sound file, it's to change the source of an image.

我正在编写一个Windows 窗体应用程序,它应该播放三个声音文件,并且在每个声音文件的末尾,它会更改图像的来源。

I can get it to play the sounds using System.Media.SoundPlayer. However, it seems to play the sound in a different thread, continuing on.

我可以让它使用System.Media.SoundPlayer. 然而,它似乎在不同的线程中播放声音,继续。

The net effect of this is that only the last sound is played and all the images are changed.

这样做的净效果是只播放最后一个声音并且所有图像都改变了。

I've tried Thread.Sleep, but it sleeps the whole GUI and after the sleep period everything happens at once and the last sound it played.

我试过了Thread.Sleep,但它使整个 GUI 休眠,并且在休眠期之后,一切都会立即发生,并且播放的最后一个声音。

UPDATE

更新

I thought PlaySynch was working, but it seems to freeze my GUI which is less than ideal. What else can I do?

我认为 PlaySynch 正在工作,但它似乎冻结了我的 GUI,这不太理想。我还可以做些什么?

采纳答案by Biri

Did you try SoundPlayer.PlaySync Method? From the help:

您是否尝试过SoundPlayer.PlaySync 方法?从帮助:

The PlaySync method uses the current thread to play a .wav file, preventing the thread from handling other messages until the load is complete.

PlaySync 方法使用当前线程播放 .wav 文件,防止线程在加载完成之前处理其他消息。

回答by RodgerB

Instead of using the Play method, use the PlaySyncmethod.

使用PlaySync方法而不是使用 Play方法。

回答by Orion Adrian

What you probably want to do is do an async sound, but then disable your UI in such a way that it doesn't respond to user response. Then once the sound is played, you re-enable your UI. This would allow you to still paint the UI as normal.

您可能想要做的是发出异步声音,然后以不响应用户响应的方式禁用您的 UI。然后,一旦播放了声音,您就可以重新启用您的 UI。这将允许您仍然像往常一样绘制 UI。

回答by Omar Kooheji

I figured out how to do it. I used PlaySynch, but I did the playing in a separate thread to the code the draws the UI. The same thread also updates the UI after each file is played.

我想出了怎么做。我使用了 PlaySynch,但我在一个单独的线程中播放了绘制 UI 的代码。在播放每个文件后,同一线程还会更新 UI。

回答by Omar Kooheji

Use this code:

使用此代码:

[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.
}