最近接的一个该修十年前VB.net的项目,产生了好多回忆啊~~
VB.NET中支持两种异常处理机制
一种是传统的On Error Resume Next
另一中是最新的Try-Catch-Finally结构化异常处理
一般只要谈到这两种机制,大家都会说结构化异常处理会好一些,他是异常处理的首选,但是结构化异常处理与传统的On Error Resume Next语句相比,其真正的优势在什么地方呢?
下面用一段代码来说明一下:
if mxDEBUG=1 then '是否启用自主错误处理
On Error Resume Next
end if
conn.Open ConStr
If Err.Number = 0 Then
On Error GoTo 0
Set GetConnection = conn
Else
SqlErrStr= chr(13) & "<br>DBA错误:<br>连接字符串:【" & ConStr & "】<br>" & chr(13)
ErrStr = ErrStr & "错误号:" & Err.number & "(H" & Hex(Err.Number) & ")<br>" & chr(13)
ErrStr = ErrStr & "错误描述:【" & Err.description & "】<br>" & chr(13)
if not conn.Errors.Count=0 then
for i=0 to conn.Errors.count-1
ErrStr = ErrStr & chr(13) & "<br>ADO错误号:H" & Hex(conn.Errors(i).Number) & "<br>" & chr(13)
ErrStr = ErrStr & "ADO错误描述:【" & conn.Errors(i).Description & "】<br>" & chr(13)
ErrStr = ErrStr & "ADO错误对象:" & conn.Errors(i).Source & "<br>" & chr(13)
ErrStr = ErrStr & "ADO_SQLState:" & conn.Errors(i).SQLState & "<br>" & chr(13)
next
end if
On Error GoTo 0
EF "<br>" & SqlErrStr & ErrStr '写入错误记录
Serr replace(ErrStr,chr(13),"")
End If
这段asp[VB]代码是我在一个程序中用来打开数据库连接的时候进行的错误处理,首先我们试着改写成流行的Try-Catch-Finally结构,呵呵,模拟一下啦
'首先定义一点东西
sub try
On Error Resume Next
end sub
sub endTry
if Err.Number = 0 then
Catch
else
OK
end if
finally
end sub
'这里开始进入正题
Try
conn.Open ConStr '可能出错的行[A]
Set GetConnection = conn
endTry
sub catch
SqlErrStr= chr(13) & "<br>DBA错误:<br>连接字符串:【" & ConStr & "】<br>" & chr(13)
ErrStr = ErrStr & "错误号:" & Err.number & "(H" & Hex(Err.Number) & ")<br>" & chr(13)
ErrStr = ErrStr & "错误描述:【" & Err.description & "】<br>" & chr(13)
if not conn.Errors.Count=0 then
for i=0 to conn.Errors.count-1
ErrStr = ErrStr & chr(13) & "<br>ADO错误号:H" & Hex(conn.Errors(i).Number) & "<br>" & chr(13)
ErrStr = ErrStr & "ADO错误描述:【" & conn.Errors(i).Description & "】<br>" & chr(13)
ErrStr = ErrStr & "ADO错误对象:" & conn.Errors(i).Source & "<br>" & chr(13)
ErrStr = ErrStr & "ADO_SQLState:" & conn.Errors(i).SQLState & "<br>" & chr(13)
next
end if
On Error GoTo 0
EF "<br>" & SqlErrStr & ErrStr '写入错误记录
Serr replace(ErrStr,chr(13),"")
end sub
sub OK
'这里是如果不出错应该继续执行的东西
'Set GetConnection = conn 这一句可以放在这里
On Error GoTo 0
end sub
sub finally
'这里是不论是否出错都可以执行的地方
end sub
上面模拟的异常处理结构在[A]那里如果出现错误,会继续执行下去,直到执行endTry,而新的Try-Catch结构则在发生异常的时候,直接跳出去找相应的Catch语句去了
在其他方面,两者的区别仅仅在实现的难易上,这个模拟想达到Try-Catch结构的效果是需要多写一点代码的.但是就是这个异常发生之后的一个小细节的不同,使得两种结构在处理大批量事务的时候表现出了截然不同的特性
假如我们的模拟语句是这样的
Try
操作1
操作2
操作3
操作4
操作5
endTry
那我们该如何捕获错误呢?
很显然,我们的模拟结构由于在发生错误之后仍然继续执行,可能会导致错误处理的延期,使得一些关键的错误被忽略
而如果使用Try-Catch结构的话,他会在错误发生之后,及时的寻找相应的异常处理代码
从而避免了错误的蔓延
那我们想到,传统的异常处理方法如果想达到这种目的,就需要在每个操作后面放置错误检测代码,类似于这样的
Try
操作1:T(1)
操作2:T(2)
操作3:T(3)
操作4:T(4)
操作5:T(5)
endTry
function T(x)
select case x
case 1
catch(1)
case 2
catch(2)
case 3
catch(3)
case 4
catch(4)
case 5
catch(5)
end function
呵呵,到了这里,Try-Catch的真正优势才能体现出来
也就是说
Try-Catch结构的优势体现在一系列相关操作所组成的一个事务的执行过程中的异常处理
在这样的情况下,如果还用传统方式来实现的话,无疑是很麻烦的
而在其他方面
比如说
1.Try-Catch实现了异常处理代码和正常业务流程的分离
传统的On Error Resume Next也是可以实现的
并且不会比Try-Catch结构麻烦
所谓的分离,不过是错误统一处理罢了
任何经过精心设计的程序结构都可以实现这种方式的
这可不是Try-Catch的专利
说了这么多,无非就是说
并不是一个新方法出来了,老方法就一无是处
并不是一个新方法出来了,就意味着老方法必须退伍了