On Error Resume Next 对速度的影响 [英] Speed impact of On Error Resume Next

查看:33
本文介绍了On Error Resume Next 对速度的影响的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

鉴于 vbscript 没有 On Error Goto MyLabel 类型的语法,如 vba,我正在考虑使用以下内容处理错误:

Given that vbscript does not have the On Error Goto MyLabel kind of syntax as with vba, I'm considering using the following to handle errors:

On Error Resume Next

'Do some stuff

If Err.Number <> 0 Then
    Err.Clear
    'Handle the error
End If

'Do some more stuff

If Err.Number <> 0 Then
    Err.Clear
    'Handle the error
End If

'...

我的问题是:这种技术对速度的影响是什么?

My question is: What would the speed impact be of this type of technique?

另外,我想知道是否有更好的方法将一些错误处理构建到 vbscript

Additionally, I would like to know if there is a better way to build some error handling into vbscript

推荐答案

  1. 比较正确实施与错误实施的速度毫无意义.如果您的脚本在没有错误处理的情况下无法满足其规范并且在使用 OERN 时速度变慢,则您必须选择另一种语言.
  2. 由于 OERN 隐藏错误,其范围应尽可能小.您的示例代码闻起来像是在全球范围内使用 OERN - 一个非常糟糕的主意.另外:在每次有风险的操作和相应的 Err.Number 检查之后,您都需要一个 Err.Clear 或On Error GoTo 0".
  3. 其他语言(例如 Python)"请求原谅比许可更容易";由于 VBScript 错误处理的不良性质,在大多数情况下,您应该先看看再跳",并且仅在绝对不可避免的情况下才使用 OERN(例如,检查注册表项是否存在,处理可能出现故障的外部资源).
  1. It makes no sense to compare the speed of a correct vs. a faulty implementation. If your script does not fullfill its specs without error handling and is to slow when using OERN, you have to choose another language.
  2. As OERN hides errors, its scope should be as small as possible. Your sample code smells like using OERN globally - a very bad idea. In addition: You need a Err.Clear or "On Error GoTo 0" after each risky operation and its corresponding check of Err.Number.
  3. In other languages (e.g. Python) "it's easier to ask forgiveness than permission"; because of the poor nature of VBScript's error handling you should "look before you leap" in most cases and use OERN only when absolutely unavoidable (e.g. check for existence of registry keys, deal with possibly failing external resources).

本地错误处理的习惯用法:

The idiom for local error handling:

Dim gaErr ' global error array
...
Sub SomeSub()
    ...
    OERN
    risky op
    gaErr = Array(Err.Number, Err.Description, ...)
    OEG0
    If gaErr(0) Then
       handle error
    ...
End Sub

如果您的规范需要全局错误处理:

If your specs make a global error handling necessary:

Dim gaErr
OERN
ret = main()
gaErr = Array(...)
OEG0
If gaErr(0) Then
   some fatal/not locally handled error occured somewhere in your script
   handle it gracefully
Else
   If ret is bad Then
      deal with this
   Else
      ask for more money
   End If
End If
WScript.Quit good/bad

Function main()
  main = ...
End Function

更新评论:

为什么全球 OERN 是邪恶的?考虑:

Why is a global OERN evil? Consider:

OERN
(1) Process/change important data
(2) Delete original data - if (1) failed you just destroyed the base of your business

OERN
(1) Process/change important data
(2) If Err.Nunber Then Backup(database, destinatiom)
(3) Continue although the Backup didn't take place, because at least three error were hidden

顺便说一句:你添加的 Err.Clear 是在错误的地方 - 你在处理错误之前丢失了错误信息.

BTW: Your addition of the Err.Clear are in the wrong place - you loose the error info before you can handle the error.

更新评论二:

考虑这个演示脚本:

' dgeh.vbs - demo global error handling

Option Explicit

' globals
Dim gWAN : Set gWAN = WScript.Arguments.Named
Dim gaErr

Dim iRet
' top-level/global OERN starts here (errors before will abort mercylessly)
On Error Resume Next
 iRet  = main() ' not more than two statements!
 gaErr = Array(Err.Number, Err.Description, Err.Source)
On Error GoTo 0
If gaErr(0) Then
   WScript.Echo "Fatal Error:", Join(gaErr, " * ")
   iRet = 1 ' or choose a better number
Else
   If iRet Then
      WScript.Echo "need one of /good, /bad, or /fatal, Mr. User!"
   Else
      WScript.Echo "all's well"
   End If
End If
WScript.Quit iRet

Function main()
  main = 2
  If gWAN.Count = 1 And (gWAN.Exists("good") Or gWAN.Exists("bad") Or gWAN.Exists("fatal")) Then
     readTheDocs
     main = 0
  End If
End Function

Sub readTheDocs()
    WScript.Echo "read Microsoft's Docs"
    If gWAN.Exists("fatal") Then
       caTastrophy
    Else
       trySomethingRisky
    End If
End Sub

Sub trySomethingRisky()
  Dim n
  If gWAN.Exists("bad") Then n = 1 / 0
  WScript.Echo "but be skeptical of the text and your interpretation"
End Sub

Sub caTastrophy()
  On Error Resume Next ' simulating the evil global OERN and not checking *each* statement
     WScript.Echo "saving the world"
     saveTheWorld
     WScript.Echo "deleting the now obsolete original"
  On Error GoTo 0
End Sub

输出

cscript dgeh.vbs /fatal
read Microsoft's Docs
saving the world
deleting the now obsolete original
all's well
echo %ERRORLEVEL%
0

由于没有 Sub saveTheWorld,您只是将错误处理、VBScript 和其他所有内容都废弃了.你甚至不能保证永远不再使用邪恶的全局 OERN,因为你 - 以及那些习惯使用它的脚本编写人员(从而证明他们是为他们的笑话而不是他们的代码付费) - 已经消失了.让我们希望调用进程不会将 ERRORLEVEL 值作为进一步删除的许可.

As there is no Sub saveTheWorld, you just made error handling, VBScript, and all the rest obsolete. You can't even promise never to use the evil global OERN again, because you - and those scripting guys who use it habitually (and thereby have proven that they are paid for their jokes, not their code) - have vanished. Let's hope the calling process won't take the ERRORLEVEL value as licence for some further deletions.

输出

cscript dgeh.vbs
need one of /good, /bad, or /fatal, Mr. User!
echo %ERRORLEVEL%
2

cscript dgeh.vbs /nix
need one of /good, /bad, or /fatal, Mr. User!

cscript dgeh.vbs /fatal /bad
need one of /good, /bad, or /fatal, Mr. User!

展示先看再跳"的策略.

demonstrate the "look before you jump" strategy.

良好案例的输出:

cscript dgeh.vbs /good
read Microsoft's Docs
but be skeptical of the text and your interpretation
all's well
echo %ERRORLEVEL%
0

显示两条消息(理所当然).

both messages are shown (and rightfully so).

现在完全不同:

cscript dgeh.vbs /bad
read Microsoft's Docs
Fatal Error: 11 * Division by zero * Microsoft VBScript runtime error
echo %ERRORLEVEL%
1

请标记第二条消息的缺失.除以零将导致执行活动 OERN 范围内的下一行(保存在 gaErr 中)并且不会盲目/无意识地继续.然后(通过 gaErr 代理)检查风险操作(执行 main() 及其所有子项所做的操作).这符合在 OERN 范围内不超过两行(有风险的操作和保存错误信息)"的规则.

Please mark the absence of the second message. The divide by zero will cause the execution of the next line in the active OERN scope (saving in gaErr) and not continue blindly/mindlessly. The risky operation (doing what main() and all its children do) is then checked (via the gaErr proxy). That honors the rule "no more than two line (risky op and saving the eror info) in an OERN scope".

这种全局错误处理的代价是:你丢失了行号信息——优雅地处理错误变得更加困难.

The price to pay for this kind of global error handling: You loose the line number info - dealing gracefully with an error becomes more difficult.

但是由于您的脚本中只有一个 OERN(从现在开始您的程序中将不再有 Sub caTastrophy()),您可以在开发和调试期间将其注释掉.

But as there is just one OERN in your script (you won't have Sub caTastrophy() in your programs from now on), you can comment it out during development and debugging.

注释掉 OERN 的输出:

output with OERN commented out:

cscript dgeh.vbs /bad
read Microsoft's Docs
E:\trials\SoTrials\answers\21901890\vbs\dgeh.vbs(46, 30) Microsoft VBScript runtime error: Division by zero

这篇关于On Error Resume Next 对速度的影响的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆