C#“using”语句和try / catch

时间:2011-06-17 09:17:45

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

我今天一直在研究如何使用“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时出现错误时捕获错误。

由于

6 个答案:

答案 0 :(得分:2)

不要发现“不可预见的”错误,因为如果真的无法预料,你无能为力。

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

对于发布的代码,存在问题。首先,try / catch可以说是尝试太多,并且鉴于你有using s,这是没有意义的(如果不是例外的话)处理。)它也捕获了一个通用的例外,这是非常沮丧的; catch es应该用于过滤那些你可以处理的东西,并按照适当的顺序。仅仅抓住throw也毫无意义。

答案 1 :(得分:2)

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

您可以查看MSDN“处理例外的最佳做法”http://msdn.microsoft.com/en-us/library/seyhszts.aspx

答案 2 :(得分:2)

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

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

因此,如果您不必使用块,则可以在类上调用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

出现InvalidOperationException
无法在未指定数据源或服务器的情况下打开连接。

连接已经打开。

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

所以这些是你应该照顾的例外。希望有所帮助!

答案 3 :(得分:1)

您不需要try..catch {throw}。这与没有try..catch块一样。

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

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

答案 4 :(得分:0)

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

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

答案 5 :(得分:0)

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