我正在使用nVLC dll在我的应用程序中使用VLC Media Player。除了一件事,它就像一个魅力。我有一个带有电影列表的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();
}
答案 0 :(得分:2)
托管调试助手'CallbackOnCollectedDelegate'...
这不是一个可捕捉的例外,因为它根本不是例外。托管调试助手是添加到调试器的辅助代码,可以在运行时检测各种不幸事件。当它看到VLC播放器试图使用已处置的委托对象时,这一步骤就会进入。如果没有调试器,您的程序将会以更糟糕的方式消失并死亡,即AccessViolationException,因为本机代码失败,因此无法捕获。
查看VLC包装器源代码,您必须仅创建m_player
实例一次以避免此故障模式。当您像现在一样反复创建它时,之前的IDiskPlayer实例不再在任何地方引用。当本机VLC代码进行回调以触发事件时,垃圾收集器将收集它们,大kaboom。包装器也没有实现我能看到的正确清理,确保本机代码在处理对象时不再触发事件。
强烈建议您制作m_player
变量 static 。只分配一次。
修复包装器需要编写相当于initializeEventsEngine()但将所有回调设置回null。这不一定是直截了当的,可能涉及线程竞赛。依赖此代码是一种负担,您可能希望继续购物。