首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >IrrKlang声音库和停止事件线程

IrrKlang声音库和停止事件线程
EN

Stack Overflow用户
提问于 2017-01-21 18:58:28
回答 1查看 295关注 0票数 0

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

代码语言:javascript
复制
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类中公开事件操作:

代码语言:javascript
复制
IsoundFinished iStopReceiver = new IsoundFinished();

现在,在我的主表单中,在我的InitializeComponent()下面的Form1()方法中有下面这一行:

代码语言:javascript
复制
iStopReceiver.IStopped += new soundFinished.OnSoundStoppedEventHandler(OnStopped);

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

代码语言:javascript
复制
 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线程调用了它--它应该为我提供一定程度的线程未对齐保护,但还是会出现各种错误,主要是

代码语言:javascript
复制
Cannot evaluate expression because a native frame is on the top of the call stack.

当然,如果不使用事件处理程序,ISound.Stop();就会从引擎中删除声音,就像它应该做的那样。我知道线程出了问题,但我不知道是怎么回事。如果有人能给我一些建议,我将不胜感激。

EN

回答 1

Stack Overflow用户

发布于 2017-01-22 09:18:26

看起来我自己解决了这个问题!这一切都是关于理解线程在Visual C#中是如何工作的。问题是这样的:我实际上暂停了后台线程,我的audioengine正在触发事件-所以‘直到我在主UI线程中执行了INVOKE之后的操作,后台线程和整个irrKlang引擎都暂停了。它无法正确地清除自身,所以它的调用堆栈被阻塞了!

使用BEGININVOKE解决了这个问题,因为它不会暂停后台任务。它让它运行。 answer上的图表给了我非常需要的信息。也许有人也需要这个答案,很高兴我帮助了自己:

代码语言:javascript
复制
private void OnStopped(object sender, EventArgs e)
        {            
            if (InvokeRequired)
            {
                BeginInvoke(new Action<object, EventArgs>(OnStopped), sender, e);
                return;
            }            

            btnStop1.PerformClick();                
        }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41778514

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档