0

我有一个关于使用音频播放引擎的外部 c++ 库 (irrKlang.dll) 的问题。现在,问题是当我从中得到一个 SoundStopped 事件并在主窗体中执行操作时,会出现各种与堆栈相关的错误。让我展示一下代码:

namespace WindowsFormsApplication4

{
    public class IsoundFinished : ISoundStopEventReceiver
    {
        public delegate void OnSoundStoppedEventHandler(object source, EventArgs e);
        public event OnSoundStoppedEventHandler IStopped;

        public void OnSoundStopped(ISound iSound, StopEventCause reason, object userData)
        {
            if (reason.ToString() == "SoundFinishedPlaying")
                IStopped?.Invoke(this, EventArgs.Empty);
        }
    }
}

这是我执行自定义操作的扩展类(例如 - 如果声音完成,则引发事件......)我正在创建它的一个实例,以便事件操作在我的主 Form1 类中公开:

IsoundFinished iStopReceiver = new IsoundFinished();

现在在我的主窗体中,我的 Form1() 方法中有这一行,就在我的 InitializeComponent() 下方:

iStopReceiver.IStopped += new soundFinished.OnSoundStoppedEventHandler(OnStopped);

它用于订阅事件处理程序。最后 - 我的 OnStopped() 方法应该在歌曲结束播放时做一些事情 - 它在同一个 Form1 上:

 private void OnStopped(object sender, EventArgs e)
        {            
            if (InvokeRequired)
            {
                Invoke(new Action<object, EventArgs>(OnStopped), sender, e);
                return;
            }            

            btnStop1.PerformClick();
        }

我的 Stop1 按钮方法是(对于那些使用 IrrKlang 的人)ISound.Stop();和几行代码,处理播放列表的显示等。虽然我已经从主 UI 线程调用它 - 这应该为我提供一定程度的线程错位保护,但出现了各种错误,主要是

Cannot evaluate expression because a native frame is on the top of the call stack.

当然,如果我在没有事件处理程序的情况下这样做,ISound.Stop(); 像它应该的那样降低引擎的声音。我知道线程发生了问题,但我不知道发生了什么。如果有人能给我一些提示,我将不胜感激。

4

1 回答 1

0

好吧,看来我已经自己解决了!这完全是为了了解线程在 Visual C# 中是如何工作的。问题是这样的:我实际上是在暂停我的音频引擎触发事件的后台线程 - 所以直到我在主 UI 线程中执行 INVOKE 后执行操作,后台线程与整个 irrKlang 引擎一起暂停。它无法正确清除自己,所以它的调用堆栈被阻塞了!

使用 BEGININVOKE 解决了这个问题,因为它不会暂停后台任务。它让它运行。这个答案的图表为我提供了我正在寻找的急需的信息。也许有人也需要这个答案,很高兴我帮助了自己:P

private void OnStopped(object sender, EventArgs e)
        {            
            if (InvokeRequired)
            {
                BeginInvoke(new Action<object, EventArgs>(OnStopped), sender, e);
                return;
            }            

            btnStop1.PerformClick();                
        }
于 2017-01-22T01:18:26.480 回答