• 利用using和try/finally语句来清理资源


            使用非托管资源的类型必须实现IDisposable接口的Dispose()方法来精确的释放系统资源。.Net环境的这一规则使得释放资源代码的职责 是类型的使用者,而不是类型或系统。因此,任何时候你在使用一个有Dispose()方法的类型时,你就有责任来调用Dispose()方法来释放资源。 最好的方法来保证Dispose()被调用的结构是使用using语句或者try/finally块。

            所有包含非托管资源的类型应该实现IDisposable接口,另外,当你忘记恰当的处理这些类型时,它们会被动的创建析构函数。如果你忘记处理这些对 象,那些非内存资源会在晚些时候,析构函数被确切调用时得到释放。这就使得这些对象在内存时待的时间更长,从而会使你的应用程序会因系统资源占用太多而速 度下降。

            幸运的是,C#语言的设计者精确的释放资源是一个常见的任务。他们添加了一个关键字来使这变得简单了。假设你写了下面的代码:public void ExecuteCommand( string connString,  string commandString )

     {  

    SqlConnection myConnection = new SqlConnection( connString );  

    SqlCommand mySqlCommand = new SqlCommand( commandString,  myConnection );  

      myConnection.Open();  

    mySqlCommand.ExecuteNonQuery();  

    }  

            这个例子中的两个可处理对象没有被恰当的释放:SqlConnection和SqlCommand。两个对象同时保存在内存里直到析构函数被调用。(这两 个类都是从System.ComponentModel.Component继承来的。)

            解决这个问题的方法就是在使用完命令和链接后就调用它们的Dispose:

    1. public void ExecuteCommand( string connString,  string commandString )  
    2. {  
    3. SqlConnection myConnection = new SqlConnection( connString );  
    4. SqlCommand mySqlCommand = new SqlCommand( commandString,  
    5.     myConnection );  
    6.   
    7. myConnection.Open();  
    8. mySqlCommand.ExecuteNonQuery();  
    9.   
    10. mySqlCommand.Dispose( );  
    11. myConnection.Dispose( );  
    12. }  

            这很好,除非SQL命令在执行时抛出异常,这时你的Dispose()调用就永远不会成功。using语句可以确保Dispose()方法被调用。当你把 对象分配到using语句内时,C#的编译器就把这些对象放到一个try/finally块内:

    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. }  

            当你在一个函数内使用一个可处理对象时,using语句是最简单的方法来保证这个对象被恰当的处理掉。当这些对象被分配时,会被编译器放到一个 try/finally块中。下面的两段代码编译成的IL是一样的

    1. SqlConnection myConnection = null;  
    2.   
    3. // Example Using clause:  
    4. using ( myConnection = new SqlConnection( connString ))  
    5. {  
    6. myConnection.Open();  
    7. }  
    8.   
    9.   
    10. // example Try / Catch block:  
    11. try {  
    12. myConnection = new SqlConnection( connString );  
    13. myConnection.Open();  
    14. }  
    15. finally {  
    16. myConnection.Dispose( );  
    17. }  

            如果你把一个不能处理类型的变量放置在using语句内,C#编译器给出一个错误,例如:

    1. // Does not compile:  
    2. // String is sealed, and does not support IDisposable.  
    3. using( string msg = "This is a message" )  
    4. Console.WriteLine( msg );  

            using只能在编译时,那些支持IDispose接口的类型可以使用,并不是任意的对象

    1. // Does not compile.  
    2. // Object does not support IDisposable.  
    3. using ( object obj = Factory.CreateResource( ))  
    4. Console.WriteLine( obj.ToString( ));  

            如果obj实现了IDispose接口,那么using语句就会生成资源清理代码,如果不是,using就退化成使用using(null),这是安全 的,但没有任何作用。如果你对一个对象是否应该放在using语句中不是很确定,宁可为了更安全:假设要这样做,而且按前面的方法把它放到using语句 中。

            这里讲了一个简单的情况:无论何时,当你在某个方法内使用一个可处理对象时,把这个对象放在using语句内。现在你学习一些更复杂的应用。还是前面那个 例子里须要释放的两个对象:链接和命令。前面的例子告诉你创建了两个不同的using语句,一个包含一个可处理对象。每个using语句就生成了一个不同 的try/finally块。等效于你写了这样的代码:

    1. public void ExecuteCommand( string connString,  
    2. string commandString )  
    3. {  
    4. SqlConnection myConnection = null;  
    5. SqlCommand mySqlCommand = null;  
    6. try  
    7. {  
    8.     myConnection = new SqlConnection( connString );  
    9.     try  
    10.     {  
    11.       mySqlCommand = new SqlCommand( commandString,  
    12.     &nbs
  • 相关阅读:
    爬虫-selenium模块
    动画《区块链100问》第4集:第一个比特币诞生啦!
    动画《区块链100问》第5集:谁是中本聪?
    动画《区块链100问》第6集:密码朋克是什么?
    动画《区块链100问》第7集:比特币是怎么发行的?
    动画《区块链100问》第8集:披萨居然卖到3亿元?
    动画《区块链100问》第9集:中本聪的继任者是谁?
    动画《区块链100问》第10集:早期比特币还能白送!
    《区块链100问》第11集:比特币为什么还没挖完?
    《区块链100问》第12集:比特币如何实现总量恒定?
  • 原文地址:https://www.cnblogs.com/muyuqianshan/p/6665288.html
Copyright © 2020-2023  润新知