【问题标题】:C# "using" statement and try/catchC# "using" 语句和 try/catch
【发布时间】:2011-09-17 01:03:41
【问题描述】:

我今天一直在研究何时如何使用“using”语句来处理我的 sql 对象。 但是,我仍然对何时以及如何捕获不可预见的错误感到困惑。我在这里有一个简单的方法,如果它是正确的还是我做错了什么,将不胜感激?

private BindingList<My_Object> Search(int ID)
{
   string strSelectStatement = 
     "SELECT 'coloumns' " +
     "FROM 'table' " +
     "WHERE ID = @ID;";

     DataTable dt = new DataTable();
     try
     {
        using (SqlConnection sqlConn = new SqlConnection(m_SQLConnectionString))
        {
          using (SqlCommand cmd = new SqlCommand(strSelectStatement, sqlConn))
          {
            cmd.Parameters.Add("@ID", SqlDbType.Int).Value = ID;
            using (SqlDataAdapter adpt = new SqlDataAdapter(cmd))
            {
               adpt.Fill(dt);
            }
          }
        }

        My_Object myObject;
        BindingList<My_Object> myObjectList = new BindingList<My_Object>();

        foreach (DataRow row in dt.Rows)
        {
          myObject = new My_Object();
          //Fill/set myObject properties and add to myObject list
        }

        return myObjectList;
     }
     catch (Exception)
     {
        //throw the the exception with its stack trace up to the main call
        throw;
     }
}

因此,如果在运行 adapter.Fill 或构建 myObject/list 时出现任何问题,我的 catch 会捕获一个错误。

谢谢

【问题讨论】:

  • 如果我在正确的道路上使用“using”语句并尝试/捕获块。

标签: c# winforms .net-3.5 exception-handling using-statement


【解决方案1】:

在 C# 中。 using 语句定义要处置的项目的范围。这可以为任何实现 IDisposable 接口的对象调用。

http://msdn.microsoft.com/en-us/library/system.idisposable.aspx

因此,如果您必须不使用 using 块,您将调用类的 dispose 方法来释放/清理对象创建的资源。

在调用实现 IDisposable 接口的类时,try/finally 模式可确保释放非托管资源,即使异常中断了您的应用程序。

如果在 using 语句的情况下引发异常,仍将调用 dispose。也可以使用语句堆叠

using (SqlConnection sqlConn = new SqlConnection(m_SQLConnectionString))
using (SqlCommand cmd = new SqlCommand(strSelectStatement, sqlConn))
          {
            cmd.Parameters.Add("@ID", SqlDbType.Int).Value = ID;
            using (SqlDataAdapter adpt = new SqlDataAdapter(cmd))
            {
               adpt.Fill(dt);
            }
          }

关于异常处理。捕获所有异常尝试捕获类或方法抛出的特定异常是不明智的。可以在 msdn 上查看异常详情,所以 SQLConnection :http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.open.aspx

无效操作异常
不指定数据源或服务器就无法打开连接。

连接已经打开。

SqlException
打开连接时发生连接级错误。如果 Number 属性包含值 18487 或 18488,则表示指定的密码已过期或必须重置。有关详细信息,请参阅 ChangePassword 方法。

所以这些是您应该满足的例外情况。希望对您有所帮助!

【讨论】:

  • 是的,我有一个 try/finally 首先我在 finally 子句中手动处理我的对象,但今天决定改为使用 using 语句,这对我来说似乎更干净。是的,我在示例中堆叠了 3 个 using 语句,SqlConnection、SqlCommand 和 SqlDataAdapter :) 感谢您的帮助!
【解决方案2】:

不要捕捉“不可预见的”错误,因为如果真的不可预见,您将无能为力。

当然,除非您希望以某种方式处理这些错误,例如记录消息 - 但系统会为您处理 - 然后它们不再是“不可预见的”,因为您正在期待它们。

至于贴出的代码,有问题。首先,try / catch 可以说是 trying 太多了,鉴于你有usings,这是没有意义的(如果不处理异常。)它还捕获一个通用异常,这是非常不鼓励的; catches 应该以适当的顺序过滤您可以处理的那些。只追throw也是没有意义的。

【讨论】:

    【解决方案3】:

    如果您对此无能为力,请不要捕获异常。如果您捕获它们是为了清理非托管资源或用于记录目的。

    您可以查看 MSDN“处理异常的最佳实践”http://msdn.microsoft.com/en-us/library/seyhszts.aspx

    【讨论】:

      【解决方案4】:

      您不需要 try..catch {throw}。这与根本没有 try..catch 块相同。

      如果要记录显示友好消息的错误,请将代码放在catch {}中。

      即使代码崩溃,仍然会在 SqlConnection 上调用 Dispose。

      【讨论】:

      • 啊,好吧,看来我理解使用,因为那基本上是对 try/finally 语句进行编码,但我需要对正确的异常处理进行更多研究 ^^
      【解决方案5】:

      您可以在 try 语句的末尾捕获多个异常。这意味着您可以捕获可能发生的每种不同类型的错误,即 InvalidOperationException / SqlException。 MSDN 在这里解释:

      http://msdn.microsoft.com/en-us/library/ms173162(v=vs.80).aspx

      【讨论】:

        【解决方案6】:

        由于您已将整个代码包含在 try/Catch 中,因此它将捕获在 try/catch 代码块中引发的所有错误。 但是不要遵循这个方法,只捕获那些你想要处理或记录的错误。 建议这样做,因为捕获错误是一种开销。

        【讨论】:

          猜你喜欢
          • 2014-06-18
          • 2014-09-30
          • 1970-01-01
          • 1970-01-01
          • 2013-08-05
          • 1970-01-01
          • 2011-06-03
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多