【问题标题】:IrrKlang Sound Library and Stop Event threadsIrrKlang 声音库和停止事件线程
【发布时间】:2017-01-21 10:58:27
【问题描述】:

我有一个关于使用音频播放引擎的外部 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();像它应该的那样降低引擎的声音。我知道线程发生了问题,但我无法弄清楚发生了什么。如果有人能给我一些提示,我将不胜感激。

【问题讨论】:

    标签: multithreading winforms audio thread-safety irrklang


    【解决方案1】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-14
      • 2014-04-21
      • 1970-01-01
      • 1970-01-01
      • 2018-09-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多