如何捕获外部异常
本文关键字:异常 外部 何捕获 | 更新日期: 2023-09-27 18:04:41
我正在使用VLC dll在我的应用程序中使用VLC媒体播放器。除了一件事,它就像一个咒语。我有一个带有电影列表的DataGridView。当我从DataGridView中选择一个电影时,它开始在由nVLC处理的面板内播放电影。我还使用过滤器来过滤DataGridView中的电影。当我这样做了几次,我得到一个错误从nVLC DLL:
CallbackOnCollectedDelegate发生
管理调试助手'CallbackOnCollectedDelegate'在'C:'Users'User'Documents'Visual Studio 2013'Projects'Soft.UltimateMovieManager'Soft.UltimateMovieManager'bin'Release'Soft.UltimateMovieManager.vshost.exe'.
附加信息:对垃圾收集进行了回调类型委托"nVLC.Implementation ! Implementation.VlcEventHandlerDelegate::调用"。这可能会导致应用程序崩溃、损坏和数据丢失。当将委托传递给非托管代码时,它们必须由托管应用程序,直到保证它们永远不会被托管调用。
问题是我抓不到那个异常。即使我在应用程序上设置了try/catch,它仍然不能被处理。
这是我可以自己解决的问题,还是我使用的nVLC dll的问题?
if (!string.IsNullOrEmpty(video_url))
{
if (pnlStartVideo != null)
{
pnlStartVideo.Dispose();
}
pnlStartVideo = new System.Windows.Forms.Panel();
pnlStartVideo.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
pnlStartVideo.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
pnlStartVideo.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
pnlStartVideo.Location = new System.Drawing.Point(pnlStartInfo.Location.X, (pnlStartInfo.Location.Y + (pnlStartInfo.Height - 1)));
pnlStartVideo.Name = "pnlStartVideo";
pnlStartVideo.Size = new System.Drawing.Size(275, 153);
pnlStartVideo.TabIndex = 3;
tpStart.Controls.Add(pnlStartVideo);
m_factory = new MediaPlayerFactory(true);
m_player = m_factory.CreatePlayer<IDiskPlayer>();
m_player.WindowHandle = pnlStartVideo.Handle;
m_player.Events.PlayerStopped += Events_PlayerStopped;
UISync ui = new UISync();
ui.Init(this);
m_media = m_factory.CreateMedia<IMedia>(video_url);
m_player.Open(m_media);
m_media.Parse(true);
m_media.Events.StateChanged += Events_StateChanged;
m_player.Play();
}
托管调试助手'CallbackOnCollectedDelegate'…
它不是一个可捕获的异常,因为它根本不是一个异常。托管调试助手是添加到调试器中的帮助代码,可以在运行时检测各种故障。当它看到VLC播放器试图使用一个处置委托对象时,它就会介入。如果没有调试器,你的程序会崩溃,并以更糟糕的方式死亡,一个AccessViolationException,也无法捕获,因为它是本机代码失败。
查看VLC包装器源代码,必须只创建一次m_player
实例以避免这种失败模式。当您像现在一样一遍又一遍地创建它时,以前的iddiskplayer实例在任何地方都不再被引用。垃圾收集器将收集它们,当本地VLC代码进行回调以触发事件时,会发生大爆炸。包装器也没有实现我所看到的适当的清理,确保在对象被处置时本机代码不能再触发事件。强烈建议将m_player
变量设置为static。只分配一次。
修复包装器将需要编写相当于initializeEventsEngine()的代码,但将所有回调函数设置为空。这并不一定是直截了当的,可能会涉及到线程竞争。依赖于这段代码是一种负担,您可能想继续购买。