zoukankan      html  css  js  c++  java
  • 【转】编写高质量代码改善C#程序的157个建议——建议69:应使用finally避免资源泄漏

    建议69:应使用finally避免资源泄漏

    除非发生让应用程序中断的异常,否则finally总是会先于return执行。finally的这个语言特性决定了资源释放的最佳位置就是在finally块中;另外,资源释放会随着调用堆栈由下往上执行。下面的代码验证了这一点,先定义一个需要释放的类:

        class ClassShouldDisposeBase : IDisposable
        {
            string _methodName;
            public ClassShouldDisposeBase(string methodName)
            {
                _methodName = methodName;
            }
            public void Dispose()
            {
                this.Dispose(true);
                GC.SuppressFinalize(this);
                Console.WriteLine("在方法:" + _methodName + "中被释放!");
            }
    
            protected virtual void Dispose(bool disposing)
            {
                if (disposing)
                {
                    //执行基本的清理代码
                }
            }
    
            ~ClassShouldDisposeBase()
            {
                this.Dispose(false);
            }
        }

    再来模拟一个调用堆栈:

            static void Main(string[] args)
            {
                Method1();
            }
    
            static void Method1()
            {
                ClassShouldDisposeBase c = null;
                try
                {
                    c = new ClassShouldDisposeBase("Method1");
                    Method2();
                }
                finally
                {
                    c.Dispose();
                }
    
            }
    
            static void Method2()
            {
                ClassShouldDisposeBase c = null;
                try
                {
                    c = new ClassShouldDisposeBase("Method2");
                }
                finally
                {
                    c.Dispose();
                }
            }

    输出:

    在方法:Method2中被释放!
    在方法:Method1中被释放!

    finally不会因为调用堆栈中存在的异常而被终止,CLR会先执行catch块,然后再执行finally块。如下:

            static void Main(string[] args)
            {
                Method3();
            }
    
            static void Method3()
            {
                ClassShouldDisposeBase c = null;
                try
                {
                    c = new ClassShouldDisposeBase("Method3");
                    Method4();
                }
                catch
                {
                    Console.WriteLine("在Method3中捕获了异常。");
                }
                finally
                {
                    c.Dispose();
                }
    
            }
    
            static void Method4()
            {
                ClassShouldDisposeBase c = null;
                try
                {
                    c = new ClassShouldDisposeBase("Method4");
                    throw new Exception();
                }
                catch
                {
                    Console.WriteLine("在Method4中捕获了异常。");
                    throw;
                }
                finally
                {
                    c.Dispose();
                }
            }

    输出:

    在Method4中捕获了异常。
    在方法:Method4中被释放!
    在Method3中捕获了异常。
    在方法:Method3中被释放!


    转自:《编写高质量代码改善C#程序的157个建议》陆敏技

  • 相关阅读:
    2月25日
    Maven启动tomcat7:run运行异常:org.apache.catalina.LifecycleException: Failed to start component
    Junit测试报错:java.lang.NoClassDefFoundError: org/hamcrest/SelfDescribing
    tomcat启动控制台乱码
    Java虚拟机内存详解
    Ajax使用
    Struts2工作流程
    java.lang.IllegalArgumentException: 'sessionFactory' or 'hibernateTemplate' is required
    Spring-Aop的两种代理方式
    springboot与dubbo整合遇到的坑
  • 原文地址:https://www.cnblogs.com/farmer-y/p/7992968.html
Copyright © 2011-2022 走看看