繁体   English   中英

C#“使用”语句并尝试/捕获

[英]C# “using” statement and try/catch

我今天一直在研究如何使用“ 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时,如果发生任何错误,我的捕获将捕获错误。

谢谢

不要捕获“无法预料的”错误,因为如果真的无法预料,您将无能为力。

除非您当然希望以某种方式处理这些错误(例如,记录消息),但是系统会为您执行这些操作,否则它们就不再是“不可预见的”,因为您已在期待它们。

至于张贴的代码,有问题。 首先,可以说try / catch 尝试太多,并且考虑到您在其中using s,这是没有意义的(如果不会处理异常)。它还捕获了一个通用异常,这在很大程度上泄气; catch应制定适当的顺序,以过滤出您可以处理的catch 仅仅throw也没有意义。

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

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

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

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

因此,如果您不必使用using块,则可以在类上调用dispose方法以释放/清理由对象创建的资源。

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

如果在using语句中抛出异常,则将继续调用dispose。 您还可以使用using语句进行堆栈

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/zh-cn/library/system.data.sqlclient.sqlconnection.open.aspx

出现InvalidOperationException
如果不指定数据源或服务器,则无法打开连接。

要么

连接已打开。

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

因此,这些是您应满足的例外情况。 希望有帮助!

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM