【问题标题】:Is Try/Catch/finally required with the Using statement in order to handle exceptions?为了处理异常,Using 语句是否需要 Try/Catch/finally?
【发布时间】:2012-01-31 09:23:28
【问题描述】:

我想知道如何使用语句处理异常? 我是否需要用 Try/Cath/Finally 子句包装 using 语句,以确保 SqlConnection 对象已关闭和处置,即使包含的代码引发异常?

Public Function GetUserAccountKeyByUsername(ByVal pUsername As String) As Int32
    If String.IsNullOrEmpty(pUsername) Then
        Throw New ArgumentNullException("pUsername", "Username is missing")
    End If

    Dim o As Object
    Dim userAccountKey As Int32
    Dim SQL As StringBuilder = New StringBuilder()

    With SQL
        .Append("SELECT USER_KEY ")
        .Append("FROM USER ")
        .Append("WHERE USERNAME = @Username ")
    End With

    Try
        Using conn As SqlConnection = New SqlConnection(ConnectionString)
            conn.Open()
            Using cmd As SqlCommand = New SqlCommand(SQL.ToString, conn)
                Try
                    cmd.CommandTimeout = Convert.ToInt32(ConfigurationManager.AppSettings("SQLQueryLimitTime"))
                    cmd.Parameters.Add(New SqlParameter("@Username", SqlDbType.VarChar)).Value = pUsername
                    o = cmd.ExecuteScalar()
                    If (o IsNot Nothing) AndAlso Not (IsDBNull(o)) Then
                        userAccountKey = Convert.ToInt32(o)
                    End If
                Catch ex As Exception
                    _log.logError(ex, cmd)
                End Try
            End Using
        End Using
    Catch ex As Exception
        _log.logError(ex, conn.ConnectionString)
    Finally
        conn.Close()
        conn.Dispose()
    End Try
    Return userAccountKey
End Function

【问题讨论】:

  • 你还有什么问题吗?
  • 如果你得到你想要的信息,不要忘记将答案标记为已接受...

标签: .net vb.net ado.net using-statement


【解决方案1】:

usingtryfinally 放入您的代码中并自动调用 .Dispose() 并最终 .Close() 因为 DbConnection.Dispose() 调用 Close(),但没有捕获,因此您需要添加catch 超过 using 块,类似这样的事情

try
{
   using(some resource)
   {
   }
}
catch(Exception)
{
}

try
{
}
catch(Exception)
{
}
finally{ }

所以看这个你可能会认为 Try/Catch/FinallyUsing 更好,因为在 using 中无论如何你都需要处理错误,但不是

如果在.Close().Dispose() 期间出现任何错误,第一个示例也会处理该错误,但在第二种情况下,您必须将try-catch 放入finally 块中。

阅读更多关于Avoiding Problems with the Using Statement (MSDN)

希望这能回答你的问题。

【讨论】:

    【解决方案2】:

    您不需要再次将其写出来,它会在已编译的代码中自动创建..

    答案在 C# 中,但在 VB.NET 中的工作方式相同

    在处理一次性对象时,在 C# 中使用块非常方便。 Disposable 对象是那些在调用 dispose 时可以显式释放它们使用的资源的对象。正如我们所知,.Net 垃圾收集是不确定的,因此您无法准确预测对象何时会被垃圾收集。

    阅读这篇文章了解更多详情:understanding ‘using’ block in C#

    CS文件代码

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    namespace BlogSamples
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (Car myCar = new Car(1))
                {
                    myCar.Run();
                }
            }
        }
    }
    

    MSIL 代码

    .method private hidebysig static void  Main(string[] args) cil managed
    {
      .entrypoint
      // Code size       37 (0x25)
      .maxstack  2
      .locals init ([0] class BlogSamples.Car myCar,
               [1] bool CS$4$0000)
      IL_0000:  nop
      IL_0001:  ldc.i4.1
      IL_0002:  newobj     instance void BlogSamples.Car::.ctor(int32)
      IL_0007:  stloc.0
      .try
      {
        IL_0008:  nop
        IL_0009:  ldloc.0
        IL_000a:  callvirt   instance void BlogSamples.Car::Run()
        IL_000f:  nop
        IL_0010:  nop
        IL_0011:  leave.s    IL_0023
      }  // end .try
      finally
      {
        IL_0013:  ldloc.0
        IL_0014:  ldnull
        IL_0015:  ceq
        IL_0017:  stloc.1
        IL_0018:  ldloc.1
        IL_0019:  brtrue.s   IL_0022
        IL_001b:  ldloc.0
        IL_001c:  callvirt   instance void [mscorlib]System.IDisposable::Dispose()
        IL_0021:  nop
        IL_0022:  endfinally
      }  // end handler
      IL_0023:  nop
      IL_0024:  ret
    } // end of method Program::Main
    

    【讨论】:

    【解决方案3】:

    是的,您需要 try catch 块,例如用于记录代码中显示的异常。 using 块确保 Dispose 被调用但不处理异常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多