• 编写高质量代码改善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个建议》陆敏技

  • 相关阅读:
    【React】哪些数据应该放到state中?
    React组件生命周期及组件之间的通信
    【Flex布局教程】语法篇
    jQuery动态创建二级下拉菜单
    Web前端工程师成长之路——知识汇总
    Jpcap使用指南
    安装/重装tomcat(组图)
    贪吃蛇小游戏(含详细思路及源代码)
    servlet中如何操作数据库
    svn的使用方法
  • 原文地址:https://www.cnblogs.com/jesselzj/p/4739094.html
Copyright © 2020-2023  润新知