• 销毁COM对象引用时内存异常。(未释放资源导致)


     public void   Disp(){
            Dispose(true);
            }
    
            /// <summary>
            /// 销毁
            /// </summary>
            /// <param name="disposing"></param>
            protected override void Dispose(bool disposing)
            {
                try
                {
                    if (disposing)
                    {
                        graphState = State.Stopped;
    
    
                        if (mediaCtrl != null && mediaCtrl1 != null)
                        {
                            mediaCtrl.Stop();
                            mediaCtrl1.Stop();
    
                        }
                        Marshal.ReleaseComObject(mediaCtrl);
                        Marshal.ReleaseComObject(mediaCtrl1);
    
    
                        mediaCtrl = null;
                        mediaEvt = null;
                        videoWin = null;
    
                        mediaCtrl1 = null;
                        mediaEvt1 = null;
                        videoWin1 = null;
    
                        if (canStep)
                        { frameStep = null; frameStep1 = null; }
                       
                        if (graphBuilder != null)
                            Marshal.ReleaseComObject(graphBuilder);
                        if (graphBuilder1 != null)
                            Marshal.ReleaseComObject(graphBuilder1);
                        graphBuilder = null; graphBuilder1 = null;
    
                     panel1.Dispose();
                       panel2.Dispose();
                        //panel1 = null;
                        //panel2 = null;
                       trackBar1.Dispose();
                        //trackBar1 = null;
                        fName = null;
                        fName1 = null;
    
    
    
    
                    }
                    base.Dispose(disposing);
                }
                catch { }
            }
    


    这是一个销毁方法。重点在于

    Marshal 类

    提供了一个方法集,这些方法用于分配非托管内存、复制非托管内存块、将托管类型转换为非托管类型,此外还提供了在与非托管代码交互时使用的其他杂项方法。

    命名空间:  System.Runtime.InteropServices
    程序集:  mscorlib(在 mscorlib.dll 中)

    Marshal 类中定义的 static 方法对于处理非托管代码至关重要。此类中定义的大多数方法通常由需要在托管和非托管编程模型之间提供桥梁的开发人员使用。例如,StringToHGlobalAnsi 方法将 ANSI 字符从指定的字符串(在托管堆中)复制到非托管堆中的缓冲区。该方法还分配大小正确的目标堆。

    当然你也可以直接从非托管的WIN API 来创建INVOKE程序。(通常也是这么使用的)

    这里使用的

    Marshal.ReleaseComObject 方法

    递减所提供的运行库可调用包装的引用计数。

     
     
    C#
    [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
    public static int ReleaseComObject(
    	Object o
    )

    参数

    o
    类型:System..::.Object

    要释放的 COM 对象。

    返回值

    类型:System..::.Int32

    o 关联的运行库可调用包装的引用计数的新值。此值通常为零,因为无论调用包装 COM 对象的托管客户端有多少,运行库可调用包装仅保留对该对象的一次引用。

     

    每当 COM 接口指针进入公共语言运行库时,该指针都包装在运行库可调用包装中。如果您不熟悉此包装的功能,请参见 运行库可调用包装

    此方法用于显式控制从托管代码使用的 COM 对象的生存期。应及时(或者在对象按指定的顺序必须释放时)使用此方法,来释放引用某些资源的基础 COM 对象。

    该运行库可调用包装具有引用计数,每次将 COM 接口指针映射到该运行库可调用包装时,此引用计数都将递增。ReleaseComObject 方法递减运行库可调用包装的引用计数。当引用计数达到零时,运行库将释放非托管 COM 对象上的所有引用,并在您试图进一步使用该对象时引发 System..::.NullReferenceException。如果从非托管代码向托管代码传递同一 COM 接口的次数超过一次,则包装上的引用计数将依次递增,而且调用 ReleaseComObject 将返回剩余引用的数目。

    注意注意:

    若要确保释放运行库可调用包装及原始 COM 对象,可构造一个循环,并从该循环调用此方法,直到引用计数达到零。

    注意注意:

    此方法使用 SecurityAction..::.LinkDemand 防止不可信代码对它进行调用;只有直接调用方才需要具有 SecurityPermissionAttribute..::.UnmanagedCode 权限。如果您的代码可从部分受信任的代码调用,则未经验证不要将用户输入传递给 Marshal 类方法。有关使用 LinkDemand 成员的重要限制,请参见 Demand 和 LinkDemand

    “折叠”图像权限

    本人声明: 个人主页:沐海(http://www.cnblogs.com/mahaisong) 以上文章都是经过本人设计实践和阅读其他文档得出。如果需要探讨或指教可以留言或加我QQ!欢迎交流!
  • 相关阅读:
    .NET:在ASP.NET中如何进行IP限制
    vim配置文件和插件
    初学Perl的感受之数据类型
    ASP.NET伪静态详解及配置
    Wayback Machine
    对单元测试的一点感悟——这是一把双刃剑
    python中使用postgres
    第三章 匿名方法
    在C#程序中使用ocx的方法
    可扩展的 “密码强度” 代码示例
  • 原文地址:https://www.cnblogs.com/mahaisong/p/2180118.html
Copyright © 2020-2023  润新知