Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 鼠标悬停事件中停止SoundPlayer_C#_Multithreading_2d Games_Soundplayer - Fatal编程技术网

C# 鼠标悬停事件中停止SoundPlayer

C# 鼠标悬停事件中停止SoundPlayer,c#,multithreading,2d-games,soundplayer,C#,Multithreading,2d Games,Soundplayer,tl;dr版本:如何在WinForms按钮的MouseDown事件中开始播放声音,并在同一按钮的MouseUp事件中停止播放 中间C#dev在这里,我一直在尝试编写一个简单的克隆 我目前一直在尝试让它只在用户单击按钮时播放彩色按钮的声音。(我交替使用“按钮”和“瓷砖”。两者都指用户将在表单上按下的彩色按钮) 我最初试过这个: public partial class frmMain : Form { private SoundPlayer soundPlayer; privat

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

中间C#dev在这里,我一直在尝试编写一个简单的克隆

我目前一直在尝试让它只在用户单击按钮时播放彩色按钮的声音。(我交替使用“按钮”和“瓷砖”。两者都指用户将在表单上按下的彩色按钮)

我最初试过这个:

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();
    }
}
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事件没有触发,因为MouseDown尚未完成(仍会播放5秒长的声音,以防有人按住按钮超过一次简单的单击)。正如Luis Tellez在评论中提到的,SoundPlayer在一个新线程上播放声音…所以我不知道为什么这个代码现在不能工作

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

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();
    }
}
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,并显示消息“Thread is running or terminated;it cannot restart”

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

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

有人能告诉我正确的方向,让声音在鼠标上停止吗?我需要使用多线程吗?我想我的问题归结到逻辑上,但我完全被卡住了谢谢您的帮助:)


顺便说一句,我有点惊讶这个问题或类似的问题还没有被问到(至少我在google搜索或stackExchange搜索中找不到它)。

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

播放方法使用新线程播放声音。如果你叫Play 在.wav文件加载到内存之前,.wav文件将 在播放开始之前加载。您可以使用LoadAsync或Load 方法将.wav文件提前加载到内存中。在.wav文件之后 已成功从流或URL加载,以后将调用播放 SoundPlayer的方法不需要重新加载.wav文件 直到声音的路径改变。如果未安装.wav文件 指定或加载失败时,播放方法将播放默认值 嘟嘟声


我曾尝试重新创建您的问题(首先,非线程方法),但通过将SoundPlayer指向确切的文件位置而不是使用流来实现,效果很好,因此请尝试研究流是如何工作的,问题可能就在那里。请注意,它甚至适用于流。
Properties.Resources.greenTilePress
背后的代码是什么?Properties.Resources.greenTilePress是一个资源(.wav文件)。我在visual studio项目中添加了该文件,因此它将包含在exe中。在您的评论之后,我再次尝试了非线程方法,它成功了(我从这里复制并粘贴了代码)。我不知道为什么它以前不起作用。谢谢你的帮助!我看不出你发布的代码中有什么原因,据我所知,它应该可以工作,如果你在GIT上有这个,我可以克隆它并测试出来。是的,第一个代码可以工作。我不知道为什么它以前对我不起作用,但我显然把事情搞砸了。非常感谢您的时间和帮助!