我有一个关于使用外部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();像它应该的那样从发动机上掉下声音。我知道线程发生了一些错误,但我无法弄清楚发生了什么。如果有人会给我一些提示,我会非常感激。
答案 0 :(得分:0)
好吧,我自己已经解决了!它是关于理解线程在Visual C#中如何工作的全部内容。问题是这样的:我实际上是在播放我的audioengine触发事件的后台线程 - 所以&#39;直到我在主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();
}