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

  • 相关阅读:
    Visual C# 2008+SQL Server 2005 数据库与网络开发14.1.2 WPF的组成
    Visual C# 2008+SQL Server 2005 数据库与网络开发13.1.3 简单记事本程序菜单设计
    Visual C# 2008+SQL Server 2005 数据库与网络开发13.1.1 菜单创建
    Feathers TextInput使KeyboardEvent失效
    UILabel 多行显示
    突破flash player的睡眠模式
    突破flash player睡眠模式 后续
    缩放UIImage
    IT菜鸟报到!
    用VMware装了Ubuntu后,安装VMware Tools
  • 原文地址:https://www.cnblogs.com/farmer-y/p/7992968.html
Copyright © 2011-2022 走看看