繁体   English   中英

在mouseUp事件上停止SoundPlayer

[英]Stop SoundPlayer on mouseUp event

tl; dr版本:如何在WinForms按钮的MouseDown事件中开始播放声音,并停止在同一按钮的MouseUp事件中播放声音?

中级C#开发人员,我一直在尝试编写一个简单的Simon克隆。

我目前只能尝试在用户单击按钮时使其播放彩色按钮的声音。 (我交替使用“按钮”和“平铺”。两者均指用户将在表单上按下的彩色按钮)

我最初尝试过:

public partial class frmMain : Form
{
    private SoundPlayer soundPlayer;

    private void btnGreenTile_MouseDown(object sender, MouseEventArgs e)
    {
        soundPlayer = new SoundPlayer(Properties.Resources.greenTileSound)
        soundPlayer.Play();
    }

    private void btnGreenTile_MouseUp(object sender, MouseEventArgs e)
    {
        soundPlayer.Stop();
    }
}

但这并没有停止声音,因为未完成MouseDown导致MouseUp事件没有触发(如果有人按住按钮的时间超过一次简单的单击,则仍会播放大约5秒钟的声音)。 正如Luis Tellez在评论中提到的那样,SoundPlayer在新线程上播放声音...所以我不知道为什么该代码现在不起作用。

因此,我研究了多线程并尝试了以下方法:

public partial class frmMain : Form
{
    private Thread soundThread = new Thread(new ParameterizedThreadStart(PlaySound));

    // Create stream objects for each sound (needed to allow SoundPlayer to use Resources)
    private Stream greenTileSound = Properties.Resources.greenTilePress;
    private Stream redTileSound = Properties.Resources.redTilePress;
    private Stream yellowTileSound = Properties.Resources.yellowTilePress;
    private Stream blueTileSound = Properties.Resources.blueTilePress;

    public frmMain()
    {
        InitializeComponent();
    }

    private void btnGreenTile_MouseDown(object sender, MouseEventArgs e)
    {
        soundThread.Start(greenTileSound); 
    }

    private void btnGreenTile_MouseUp(object sender, MouseEventArgs e)
    {
        soundThread.Abort();
    }

    // Have to use object as parameter because ParamterizedThreadStart() only takes object arguments
    private static void PlaySound(object soundToPlay)
    {
        SoundPlayer soundPlayer = new SoundPlayer((Stream)soundToPlay);
        soundPlayer.Play();
    }
} 

使用上面的代码,它不会停止在MouseUp上播放声音,甚至更好的是,它会引发ThreadStateException并显示消息“线程正在运行或终止;它无法重新启动”。

您可能会说,我只是在尝试编写此代码时才了解多线程。 我必须使用ParameterizedThreadStart,因为它在线程启动时调用的方法PlaySound()需要使用与播放器按下的彩色按钮相对应的资源(.wav文件)将参数传递给soundPlayer。

然后我以为也许我应该尝试使用soundThread.Suspend()而不是soundThread.Abort(),但是Suspend已被弃用...

谁能指出我正确的方向,以使声音在MouseUp上停止播放? 我需要使用多线程吗? 我认为我的问题只能归结为逻辑,但我完全陷入困境。 感谢您提供的所有帮助! :)

附带说明一下,对于这个问题或尚未提出类似要求的问题,我感到有些惊讶(至少在Google搜索或stackExchange搜索中找不到)。

您可以在文档中看到play()方法在其他线程中运行,您可以在它之后执行其他操作,并且它应该运行,因此第一种方法的问题与您的想法有所不同。

Play方法使用新线程播放声音。 如果在.wav文件加载到内存之前调用Play,则将在回放开始之前加载.wav文件。 您可以使用LoadAsync或Load方法将.wav文件预先加载到内存中。 从流或URL成功加载.wav文件后,将来对SoundPlayer的播放方法的调用将无需重新加载.wav文件,直到声音的路径发生变化为止。 如果未指定.wav文件或加载失败,则Play方法将播放默认的提示音。

http://msdn.microsoft.com/en-us/library/system.media.soundplayer.play%28v=vs.110%29.aspx

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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