簡體   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