如何捕获外部异常

时间:2015-07-25 11:57:27

标签: c# .net dll datagridview vlc

我正在使用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();
}

1 个答案:

答案 0 :(得分:2)

  

托管调试助手'CallbackOnCollectedDelegate'...

这不是一个可捕捉的例外,因为它根本不是例外。托管调试助手是添加到调试器的辅助代码,可以在运行时检测各种不幸事件。当它看到VLC播放器试图使用已处置的委托对象时,这一步骤就会进入。如果没有调试器,您的程序将会以更糟糕的方式消失并死亡,即AccessViolationException,因为本机代码失败,因此无法捕获。

查看VLC包装器源代码,您必须仅创建m_player实例一次以避免此故障模式。当您像现在一样反复创建它时,之前的IDiskPlayer实例不再在任何地方引用。当本机VLC代码进行回调以触发事件时,垃圾收集器将收集它们,大kaboom。包装器也没有实现我能看到的正确清理,确保本机代码在处理对象时不再触发事件。

强烈建议您制作m_player变量 static 。只分配一次。

修复包装器需要编写相当于initializeEventsEngine()但将所有回调设置回null。这不一定是直截了当的,可能涉及线程竞赛。依赖此代码是一种负担,您可能希望继续购物。