我想知道如何使用语句处理异常? 我是否需要使用 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
答案 0 :(得分:10)
using
将try
和finally
放入您的代码中,并自动调用.Dispose()
,最后.Close()
调用DbConnection.Dispose()
调用Close()
},但没有捕获,所以你需要在catch
块上添加using
,这样的事情
try
{
using(some resource)
{
}
}
catch(Exception)
{
}
VS
try
{
}
catch(Exception)
{
}
finally{ }
所以看看这个你可能会认为尝试/抓住/最后比使用更好,因为在using
中你需要处理错误, 但不是。
如果在.Close()
或.Dispose()
期间出现任何错误,第一个示例也会处理,但在第二种情况下,您必须将try-catch
放入finally
块。
详细了解Avoiding Problems with the Using Statement (MSDN)
希望这能回答你的问题。
答案 1 :(得分:3)
你不需要再把它写出来,它会在编译代码中自动创建..
答案在C#中,但在VB.NET中的工作方式相同
在处理一次性物体时,使用C#中的块非常方便。一次性对象是那些可以在调用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
答案 2 :(得分:2)
是的,你需要try catch块,例如用于记录代码中显示的异常。 using块确保调用Dispose但不处理异常。