是否需要使用Using语句来尝试/捕获/最终处理异常?

Jon*_*nas 4 .net vb.net ado.net using-statement

我想知道如何使用语句处理异常?我是否需要使用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
Run Code Online (Sandbox Code Playgroud)

Ama*_*ure 11

using看跌期权tryfinally在你的代码,并自动调用.Dispose()并最终.Close()堂妹DbConnection.Dispose()电话Close(),但没有赶上,所以你需要添加catchusing块,一些这样的事

try
{
   using(some resource)
   {
   }
}
catch(Exception)
{
}
Run Code Online (Sandbox Code Playgroud)

VS

try
{
}
catch(Exception)
{
}
finally{ }
Run Code Online (Sandbox Code Playgroud)

所以看看这个你可能会认为Try/Catch/Finally使用更好,因为using在任何情况下你需要处理错误,但事实并非如此.

如果有任何错误时.Close().Dispose()发生时,第一个样品将处理太,但在第二种情况下,你将不得不把try-catchfinally块.

阅读有关避免使用语句(MSDN)的问题的更多信息

希望这能回答你的问题.


Pra*_*ana 4

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

\n\n

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

\n\n

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

\n\n

阅读这篇文章了解更多详细信息:Understanding \xe2\x80\x98using\xe2\x80\x99 block in C#

\n\n

CS文件代码

\n\n
using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nnamespace BlogSamples\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            using (Car myCar = new Car(1))\n            {\n                myCar.Run();\n            }\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

MSIL代码

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