【问题标题】:How to catch a external exception如何捕获外部异常
【发布时间】:2015-07-25 11:57:27
【问题描述】:

我正在使用 nVLC 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::Invoke'。 这可能会导致应用程序崩溃、损坏和数据丢失。什么时候 将委托传递给非托管代码,它们必须由 托管应用程序,直到保证它们永远不会 调用。

问题是我无法捕捉到那个例外。即使我在应用程序本身上设置了 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();
}

【问题讨论】:

    标签: c# .net dll datagridview vlc


    【解决方案1】:

    托管调试助手“CallbackOnCollectedDelegate”...

    它不是可捕获的异常,因为它根本不是异常。托管调试助手是添加到调试器的帮助代码,可以在运行时检测各种事故。当它看到 VLC 播放器尝试使用已处置的委托对象时,这一步骤就会介入。如果没有调试器,您的程序将会崩溃并以更糟糕的方式死亡,即 AccessViolationException,也无法捕获,因为它是失败的本机代码。

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

    强烈建议将m_player 变量设为静态。只分配一次。

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

    【讨论】:

    • 非常感谢.. 听起来这应该可行。我将在今天晚些时候尝试这个,并在它起作用时将它标记为我的问题的答案。我一直在寻找一个不错的 VLC 包装器,但没有运气,你知道有什么好的 VLC 包装器吗?
    • 嗯,不,只有由程序员调试并将其更改回馈给开源项目的包装器才能相对无故障地工作。
    猜你喜欢
    • 2021-06-13
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 2012-03-16
    • 1970-01-01
    • 1970-01-01
    • 2014-12-04
    • 2016-12-13
    相关资源
    最近更新 更多