24

我知道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 未打开或产生某种错误,如何向用户显示?

4

9 回答 9

25

编写在块内的代码没有什么特别之处using- 只需使用 atry.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块并确保自己正确处理(正如亚当在他的回答中所建议的那样)。

于 2012-04-17T15:00:16.877 回答
11

using不提供任何后门进入catch.

只需手动扩展它(在使用 IMO 中使用 try/catch 没有意义):

SqlConnection conn = null;

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

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

在大多数情况下,我更喜欢using在 a中包装try-catch或嵌入 a以避免代码在编译后以嵌套的形式结束。但是,如果您只需要在.try-catchusingtry-catchusing

于 2012-04-17T14:59:59.853 回答
8
class SqlConnection
{
   using(sqlConnection)
   {

   }
}

class Consumer
{
   try
  {

  }
  catch(SqlException)
  {

  }

}

由类的使用者决定如何处理异常。

于 2012-04-17T15:07:06.343 回答
6

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

但是,我要补充一点,这是放置 try/catch的错误位置,特别是如果您的目标是“向用户展示”一条消息。让异常发生在这个级别,并允许它在堆栈中冒泡到处于更好位置以知道如何响应它的代码。

换句话说,让您的代码示例保持原样。不要在该方法中添加任何新内容。但也许调用此方法的代码应该考虑如何处理数据库中的异常......任何异常。

于 2012-04-17T15:09:19.800 回答
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
    }                
} 
于 2012-04-17T15:00:58.633 回答
2

这与没有它的方式相同。

using(SqlConnection conn = new SqlConnection(connString))
{
  try{
    //some code
  }
  catch(SqlException e)
    MessageBox.Show(e.Message);
}
于 2012-04-17T15:00:30.827 回答
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?
}       
于 2012-04-17T15:02:24.510 回答
0

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

于 2016-08-05T20:03:03.443 回答
-3

如果要捕获 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 语句内。这意味着执行将到达 using 块的末尾。因此,您的对象将被丢弃,您不必担心内存泄漏(损坏,

于 2012-12-27T06:50:41.560 回答