我有一个关于使用外部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();现在,在我的主表单中,在我的InitializeComponent()下面的Form1()方法中有下面这一行:
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();就会从引擎中删除声音,就像它应该做的那样。我知道线程出了问题,但我不知道是怎么回事。如果有人能给我一些建议,我将不胜感激。
发布于 2017-01-22 09:18:26
看起来我自己解决了这个问题!这一切都是关于理解线程在Visual C#中是如何工作的。问题是这样的:我实际上暂停了后台线程,我的audioengine正在触发事件-所以‘直到我在主UI线程中执行了INVOKE之后的操作,后台线程和整个irrKlang引擎都暂停了。它无法正确地清除自身,所以它的调用堆栈被阻塞了!
使用BEGININVOKE解决了这个问题,因为它不会暂停后台任务。它让它运行。 answer上的图表给了我非常需要的信息。也许有人也需要这个答案,很高兴我帮助了自己:
private void OnStopped(object sender, EventArgs e)
{
if (InvokeRequired)
{
BeginInvoke(new Action<object, EventArgs>(OnStopped), sender, e);
return;
}
btnStop1.PerformClick();
}https://stackoverflow.com/questions/41778514
复制相似问题