【问题标题】:NAudio Cross-Thread Call Exception When Audio Playback Ends On It's Own音频播放自行结束时 NAudio 跨线程调用异常
【发布时间】:2016-04-17 16:35:44
【问题描述】:

我有一个使用 NAudio 进行音频播放的 C# WinForms 应用程序。

这是播放按钮的代码:

    private void btnPlayQuestionAudio_Click(object sender, EventArgs e)
    {
        if (btnPlayQuestionAudio.Text == "?")
        {
            try
            {
                LoadQuestionAudio(lstQuestions[glbintIndex].strQuestionAudio);
                QuestionAudioPlayer.Play();
                btnPlayQuestionAudio.Text = "?";
                QuestionAudioPlayer.PlaybackStopped += QuestionAudioPlayer_PlaybackStopped;
            }
            catch (FormatException fe)
            {
                QuestionAudioPlayer.Stop();
                btnPlayQuestionAudio.Text = "?";
                MessageBox.Show(fe.ToString(), "oops.", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        else if (btnPlayQuestionAudio.Text == "?")
        {
            QuestionAudioPlayer.Stop();
            btnPlayQuestionAudio.Text = "?";
        }
    }

这是停止播放的代码:

    private void QuestionAudioPlayer_PlaybackStopped(Object Sender, EventArgs e)
    {
        btnPlayQuestionAudio.Text = "?";
    }

问题:当音频完全播放并且“QuestionAudioPlayer_PlaybackStopped”事件处理程序执行时,应用程序在“QuestionAudioPlayer_PlaybackStopped”事件处理程序中崩溃,并出现以下异常:

“System.Windows.Forms.dll 中发生了“System.InvalidOperationException”类型的未处理异常。附加信息:跨线程操作无效:控件“btnPlayQuestionAudio”从创建它的线程以外的线程访问。”

这并不总是发生。我看不到这个新线程是在哪里创建的。我尝试将所有播放代码放在后台工作人员中,但结果证明这比它的价值更麻烦。我只在我需要做的事情超过 UI 线程可以安全处理且无需花费很长时间的事情时才使用后台工作人员。如何防止代码在新线程上执行?或者除了后台工作人员之外还有其他方法可以处理这个问题吗?

【问题讨论】:

    标签: c# call naudio


    【解决方案1】:

    您的“QuestionAudioPlayer_PlaybackStopped”方法在不同的线程上下文中被调用。您必须在那里进行“InvokeRequired”模式检查,如下所示:

    private void QuestionAudioPlayer_PlaybackStopped(object sender, EventArgs e)
    {
        if( this.InvokeRequired )
        {
            // We're in an asynchronous context...
            MethodInvoker del = delegate
                {
                    this.QuestionAudioPlayer_PlaybackStopped(sender, e);
                };
            this.Invoke(del);
            return;
        }
    
        // This will be executed in the synchronous context:
        btnPlayQuestionAudio.Text = "?";
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-18
      • 1970-01-01
      • 2012-07-14
      • 1970-01-01
      相关资源
      最近更新 更多