使用语句捕获异常

时间:2012-04-17 14:57:27

标签: c# using

我知道Using语句处理了正在创建的对象。就像我想做这样的事情:

    Using(SqlConnection conn = new SqlConnection(connString))
    {
      //some code
      //How to show the users if conn is not opened up or generated some kind of error?
    }

如果没有打开conn或产生某种错误,如何显示用户?

9 个答案:

答案 0 :(得分:22)

using块中编写的代码没有什么特别之处 - 只需使用try.catch来处理异常:

using(SqlConnection conn = new SqlConnection(connString))
{
    try
    {
        conn.Open();
        // do more stuff here......

    }
    catch(SqlException sqlEx)
    {
       // log error and possibly show to user in a MessageBox or something else
    }
}

using(...) { ... }块本身设计为 ,以确保它“封装”的资源/对象在不再需要时被妥善处理。使用using语句本身无法处理错误。

因此,如果您希望仅创建对象失败,那么您必须将整个using块放在try ... catch块中,或者回退到try ... catch ... finally块并确保自己妥善处理(正如亚当在答案中所说)。

答案 1 :(得分:9)

using并未向catch提供任何后门。

只需手动展开它(使用IMO中的try / catch没有任何意义):

SqlConnection conn = null;

try
{
    conn = new SqlConnection("");
}
catch ...
{

}
finally
{
    if (conn != null)
        conn.Dispose();
}

我倾向于将using包裹在try-catch中,或者在try-catch中将using包含在try-catch中,以避免代码以嵌套方式结束using一旦编译完毕。但是,如果您只需要覆盖{{1}}中的大量代码的一小部分,我就会更精细并嵌入它。

答案 2 :(得分:8)

class SqlConnection
{
   using(sqlConnection)
   {

   }
}

class Consumer
{
   try
  {

  }
  catch(SqlException)
  {

  }

}

由班级的消费者决定如何处理异常。

答案 3 :(得分:6)

正如其他答案所述,只需添加正常的try / catch。

但是,如果您的目标是“向用户显示”消息,我会补充说,这是错误放置try / catch,尤其是的地方。让异常发生在这个级别,并允许它将堆栈冒泡到代码,以便知道如何响应它。

换句话说,保持代码样本不变。不要向该方法添加任何新的... 。但也许调用此方法的代码应该考虑如何处理异常...来自数据库的任何异常。

答案 4 :(得分:3)

只是以正常的方式:

要么

try
{
    using(SqlConnection conn = new SqlConnection(connString)) 
    { 
      //some code        
    } 
}
catch (Exception exc)
{
    //handle error
}

using(SqlConnection conn = new SqlConnection(connString)) 
{ 
    try
    {
        //some code 
    }
    catch (Exception exc)
    {
        //handle error
    }                
} 

答案 5 :(得分:2)

就像你没有这样做一样。

using(SqlConnection conn = new SqlConnection(connString))
{
  try{
    //some code
  }
  catch(SqlException e)
    MessageBox.Show(e.Message);
}

答案 6 :(得分:0)

你不是在using

中进行的
try
{
    using(SqlConnection conn = new SqlConnection(connString))
    {
        // Some code for when "conn" is succesfully instantiated
    }
}
catch (SomeSpecificConnectionInstantiationException ex)
{
    // Use ex to handle a bizarre instantiation exception?
}       

答案 7 :(得分:0)

当你在try / catch中嵌入using()块时,using()块确实会保证调用Dispose。但是,如果使用块中任何位置的非托管代码抛出异常,则使用()只会吃掉它,它将无法访问您的捕获。在using()块中使用try / catch,跳过using()并执行try / catch / finally,或者使用奇怪的“using()try”语法和catch块(这会留下奇数个括号和很可能会混淆那些后来遇到它的中级程序员。

答案 8 :(得分:-2)

如果要捕获using块内部代码抛出的异常,最好在using语句中使用try {} catch(){}。现在,考虑以下两个示例 - 这解释了为什么在using语句中使用try-catch块是一个好习惯。

  

示例1

       try{
           using(SomeObject so = new SomeObject){
              // Perform some tasks
           }
       }catch(SomeException objSomeException){
             // Perform some actions, if exception occurs
       }
  

示例2

       using(SomeObject so = new SomeObject){
           try{    
               // Perform some tasks
              }catch(SomeException objSomeException){
                   // Perform some actions, if exception occurs
              }
       }

现在,如果在using语句中执行某些任务时发生异常,则两个示例都会产生相同的结果。简单的答案是不,原因???

当示例1中发生异常时,它会被catch块捕获 - 而不会到达using块的末尾。因此,示例1中的someObject将无法正确处理。即使CLR很慷慨(你不应该指望) - 示例1中someObject使用的内存将无法恢复(或者最终它将在第2代GC集合中结束)。

在示例2的情况下,catch块在using语句中。这意味着执行将到达使用块的末尾。因此,您的对象将被丢弃,您不必担心内存泄漏(腐败,