zoukankan      html  css  js  c++  java
  • Effective C# Item15:利用using和try/finally语句来清理资源

        在内存资源分配方面,.NET可以分为托管资源和非托管资源两部分。对于托管资源,.NET框架会负责进行垃圾回收的工作;对于非托管的资源,我们需要手动去释放资源。通常情况下,我们使用IDisposable接口中的Dispose()方法释放资源,而调用Dispose()方法的责任,由资源的拥有者或者对象的拥有者执行,即我们这些程序员,确保调用Dispose()方法的最佳方式就是使用using或者try/finally语句块。

        所有拥有非托管资源的类型,都应该实现IDisposable接口,另外作为一种保障措施,这种类型还会创建一个终结器,以防止我们忘记调用Dispose()方法,如果我们忘记了调用Dispose()方法,那么其中的非内存资源会在随后终结器执行时被释放。这样对象在内存中存留的时间会比较长,应用程序对资源的清理也比较慢。

        我们可以使用using的方式来强制调用Dispose()方法,查看以下代码。

    代码
    1 public void ExecuteCommand( string connString,
    2 string commandString )
    3 {
    4 using ( SqlConnection myConnection = new
    5 SqlConnection( connString ))
    6 {
    7 using ( SqlCommand mySqlCommand = new
    8 SqlCommand( commandString,
    9 myConnection ))
    10 {
    11 myConnection.Open();
    12 mySqlCommand.ExecuteNonQuery();
    13 }
    14 }
    15 }
        上述代码中,SqlConnection和SqlCommand是两个需要释放资源的地方,其中在变量声明时,使用了using,它的作用和以下的代码相同。

    代码
    1 SqlConnection myConnection = null;
    2
    3 // Example Using clause:
    4 using ( myConnection = new SqlConnection( connString ))
    5 {
    6 myConnection.Open();
    7 }
    8
    9 // example Try / Catch block:
    10 try {
    11 myConnection = new SqlConnection( connString );
    12 myConnection.Open();
    13 }
    14 finally {
    15 myConnection.Dispose( );
    16 }
        注意,如果我们对一个没有实现IDisposable接口的对象使用using语句,那么C#编译器会产生错误,只有当编译时类型实现了IDisposable接口时,using语句才会正常编译。

        我们可以使用as进行类型转换,以防止出现编译错误。

    1 object obj = Factory.CreateResource( );
    2 using ( obj as IDisposable )
    3 Console.WriteLine( obj.ToString( ));
        上述代码中,如果obj没有实现IDisposable接口,那么变为using(null),这种做法很安全,不会产生变异错误,只是不会做任何事情。

        在释放某些对象的资源时,我们会发现有些类型既支持Dispose()方法,也支持Close()方法,例如SqlConnection类型,我们也可以通过调用Close()方法来释放资源。

        Dispose()方法和Close()方法的区别:Dispose()方法除了释放资源之外,还会通知垃圾收集器对该对象不再需要执行终结操作,它是通过调用GC.SuppressFinalize()方法来实现的;Close()方法一般不会这么处理,因此在调用了Close()方法的对象,依然会停留在终结队列中。因此,我们应该优先调用Dispose()方法。

        Dispose()方法不会将对象从内存上删除,它只是让对象释放非托管资源,这意味着如果释放的是仍被使用的对象,那么可能会遇到一些问题,因此,我们不应该释放那些仍然被程序其他地方引用的对象。

  • 相关阅读:
    洛谷 P1244 青蛙过河
    洛谷 P1004 方格取数
    洛谷 CF894A QAQ
    【题解】洛谷 P5506 封锁
    洛谷 P3884 [JLOI2009]二叉树问题
    Bzoj4894 天赋
    Bzoj4893 项链分赃
    Bzoj3583 杰杰的女性朋友
    POJ3233 Matrix Power Series
    UOJ#204 【APIO2016】Boat
  • 原文地址:https://www.cnblogs.com/wing011203/p/1646882.html
Copyright © 2011-2022 走看看