Влияние на скорость при ошибке Resume Next
При условии vbscript
не имеет On Error Goto MyLabel
вид синтаксиса, как с vba
Я рассматриваю возможность использования следующих ошибок:
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
'...
Мой вопрос: какое влияние на скорость будет оказывать этот тип техники?
Кроме того, я хотел бы знать, есть ли лучший способ встроить обработку ошибок в vbscript
2 ответа
- Нет смысла сравнивать скорость правильной и ошибочной реализации. Если ваш скрипт не выполняет свои спецификации без обработки ошибок и работает медленно при использовании OERN, вам нужно выбрать другой язык.
- Поскольку OERN скрывает ошибки, его область действия должна быть как можно меньше. Ваш пример кода пахнет как использование OERN во всем мире - очень плохая идея. Кроме того: Вам нужно Err.Clear или "On Error GoTo 0" после каждой рискованной операции и соответствующей проверки Err.Number.
- В других языках (например, Python) "проще просить прощения, чем разрешения"; из-за плохой природы обработки ошибок VBScript в большинстве случаев вы должны "смотреть перед тем, как прыгнуть", и использовать OERN только тогда, когда это абсолютно неизбежно (например, проверка на наличие ключей реестра, устранение возможных сбоев внешних ресурсов).
Идиома для локальной обработки ошибок:
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
Если ваши спецификации требуют глобальной обработки ошибок:
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
(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 находится не в том месте - вы теряете информацию об ошибке, прежде чем сможете ее обработать.
Обновление по комментарию II:
Рассмотрим этот демонстрационный скрипт:
' 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 в качестве лицензии для некоторых дальнейших удалений.
выход для
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!
продемонстрировать стратегию "посмотри, прежде чем прыгать".
вывод для хорошего случая:
cscript dgeh.vbs /good
read Microsoft's Docs
but be skeptical of the text and your interpretation
all's well
echo %ERRORLEVEL%
0
оба сообщения показаны (и это справедливо).
а теперь что-то совсем другое:
cscript dgeh.vbs /bad
read Microsoft's Docs
Fatal Error: 11 * Division by zero * Microsoft VBScript runtime error
echo %ERRORLEVEL%
1
Пожалуйста отметьте отсутствие второго сообщения. Деление на ноль приведет к выполнению следующей строки в активной области OERN (сохранение в gaErr) и не будет продолжаться вслепую / бездумно. Рискованная операция (выполняющая то, что делают main() и все ее дочерние элементы) затем проверяется (через прокси-сервер gaErr). Это соблюдает правило "не более двух строк (рискованно и сохраняя информацию об ошибках) в пределах OERN".
Цена за такую глобальную обработку ошибок: вы теряете информацию о номере строки - изящно справляться с ошибкой становится сложнее.
Но поскольку в вашем сценарии есть только одно OERN (с этого момента в ваших программах не будет Sub caTastrophy()), вы можете закомментировать его во время разработки и отладки.
вывод с OERN закомментирован:
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
Когда я использую обработку ошибок в Vbscript, я не нахожу, что это имеет проблему с производительностью. Однако в моих программах это обычно делает что-то довольно простое, например, вывод оператора Failed в файл журнала. wscript.quit
так что я никогда не находил это для снижения производительности системы. На приведенном вами примере обычно добавляется On Error Goto 0
после последнего End If
где вы проверяете на ошибку. Это может привести к тому, что ошибка не будет сброшена, поэтому при следующем выполнении проверки она будет по-прежнему неправильно сохранять старое значение ошибки.