• 浅尝EffectiveCSharp_8


    Item 15: Utilize using and try/finally for Resource Cleanup 使用using 和 try/finally 进行资源清理

    使用非托管系统资源的类型应该用Dispose()方法来释放。.NET环境的规则是:使用该类型的代码对它有释放的责任,而不是该类型或者系统。The  rules of the .NET environment make that the responsibility of the code that uses the type, not the responsibility of the type or the system.因此,当你使用的方法有Dispose()方法,那么你应该记得调用Dispose()方法来释放它。保证Dispose()的最好方法就是使用using声明或者是try/finally块。
    ●C#语言设计者知道明确的释放资源会是a common task。他们增加了关键字来使它更简单。加入你写了一下代码

    public void ExecuteCommand(string connString,string commandString)
    {
    SqlConnection myConnection
    = new SqlConnection(connString);
    SqlCommand mySqlCommand
    = new SqlCommand(commandString,myConnection);
    myConnection.Open();
    mySqlCommand.ExecuteNonQuery();
    }

     在这个例子中,两个可释放对象没有惊醒正确的清理:SqlConnection and SqlCommand。这些对象依然存在在内存中,直到finalizers被调用。下面是一个修改的例子

    public void ExecuteCommand(string connString,string commandString)
    {
    SqlConnection myConnection
    = new SqlConnection(connString);
    SqlCommand mySqlCommand
    = new SqlCommand(commandString,myConnection);
    myConnection.Open();
    mySqlCommand.ExecuteNonQuery();
    mySqlCommand.Dispose();
    myConnection.Dispose();
    }

    这个已经比较好了,除非SQL执行时出现了异常被抛出。那样的话,调用的Dispose()就不会发生。下面使用using声明来保证Dispose()被调用

    public void ExecuteCommand(string connString, string commandString)
    {
    using (SqlConnection myConnection = new SqlConnection(connString))
    {
    using (SqlCommand mySqlCommand = new SqlCommand(commandString, myConnection))
    {
    myConnection.Open();
    mySqlCommand.ExecuteNonQuery();
    }
    }
    }

    无论你什么时候在函数中使用一个可释放 的对象,使用using是保证对象释放的最简单方法。

     

    ●如果你对一个不支持IDisposable接口的变量使用using,编译器会产生一个错误。比如:如果obj实现IDisposable接口,using声明就会产生清楚代码。

    // Does not compile:
    // String is sealed, and does not support IDisposable.
    using (string msg = "This is a message")
    Console.WriteLine(msg);
    using声明只有在编译时类型支持IDisposable接口的情况下有用。
    // Does not compile.
    // Object does not support IDisposable.
    using (object obj = Factory.CreateResource())
    Console.WriteLine(obj.ToString());

    // The correct fix.
    // Object may or may not support IDisposable.
    object obj = Factory.CreateResource();
    using (obj as IDisposable)
    Console.WriteLine(obj.ToString());

    ●using声明是一个套一个。现在来看看try/catch块

    public void ExecuteCommand(string connString,
    string commandString)
    {
    SqlConnection myConnection
    = null;
    SqlCommand mySqlCommand
    = null;
    try
    {
    myConnection
    = new SqlConnection(connString);
    mySqlCommand
    = new SqlCommand(commandString,myConnection);
    myConnection.Open();
    mySqlCommand.ExecuteNonQuery();
    }
    finally
    {
    if (mySqlCommand != null)
    mySqlCommand.Dispose();
    if (myConnection != null)
    myConnection.Dispose();
    }
    }

     现在已经解决了两个非常显著的问题,但是这里还有点细微的差别。有的类型既支持Dispose方法也支持Close方法来释放对象。SqlConnection就是这样的一种类型。你也可以这样关闭SqlConnection:

    public void ExecuteCommand(string connString,
    string commandString)
    {
    SqlConnection myConnection
    = null;
    try
    {
    myConnection
    = new SqlConnection(connString);
    SqlCommand mySqlCommand
    = new SqlCommand(commandString,myConnection);
    myConnection.Open();
    mySqlCommand.ExecuteNonQuery();
    }
    finally
    {
    if (myConnection != null)
    myConnection.Close();
    }
    }

     这里connection并没有被关闭。Dispose方法和Close方法并不完全一样,Dispose在释放了资源后,还通知了GC去处理,它调用了GC.SuppressFinalize()。而Close没有这么做,因此对象依然在finalization队列。如果你能选择,Dispose() is better than Close().


     

  • 相关阅读:
    动静分离和前后端分离相关
    Nginx搭建动态静态服务器
    动态资源与静态资源
    LVS与Keepalived
    Tomcat实现多主多备
    Keepalived实现心跳检测实现自动重启
    nginx+keepalived简单双机主从热备
    keepalived安装
    php与java通用AES加密解密算法
    PHP修改memory_limit的三种办法
  • 原文地址:https://www.cnblogs.com/TivonStone/p/1756280.html
Copyright © 2020-2023  润新知