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个建议》陆敏技

  • 相关阅读:
    洛谷P1036 选数
    洛谷 P1009 阶乘之和
    codevs 4165 ​高精度求阶乘
    codevs 1553 互斥的数
    P2421 A-B数对(增强版)
    51nod 1081 子段求和
    codevs 3054 高精度练习-文件操作
    无聊写的高精的斐波那契数列
    51nod 1347 旋转字符串
    51nod 1212 无向图最小生成树(Kruskal模版题)
  • 原文地址:https://www.cnblogs.com/jesselzj/p/4739094.html
Copyright © 2011-2022 走看看