Я всегда задавался вопросом: как печально известный оператор VB.NET «Включение ошибки снова» преобразуется в CIL? Включает ли он каждую линию с попыткой ... ловит?Выполнение CIL On Error Resume Next
ответ
Goto.
Вы не можете комбинировать try-catch с устаревшей обработкой ошибок одним способом. Когда вы используете On Error Resume Next
, каждая строка кода в методе получает метку, а также уникальный идентификатор. В коде псевдо-C#:
int currentId = 0;
Label1:
currentId = 1;
Line1();
Label2:
currentId = 2;
Line2();
Label3:
currentId = 3;
Line3();
Exit:
Весь метод обернут в попытку поймать. Когда удастся исключение, обработчик catch проверит currentId
и сделает простой goto
на следующей метке в строке (и установлен ProjectError
). В нашем случае, это будет выглядеть примерно так:
try
{
...
}
catch (Exception ex)
{
ProjectData.SetProjectError(ex);
if (currentId == 1) goto Label2;
if (currentId == 2) goto Label3;
if (currentId == 3) goto Exit;
}
Имейте в виду, что это всего лишь деталь реализации я получил от декомпиляции приложения VB.NET. Единственное контрактное поведение - это то, что определено в On Error Resume Next
, что в основном сводится к «заданию ошибки проекта и продолжению следующего утверждения».
Здесь вы идете:
Public Sub A()
End Sub
Public Sub B()
End Sub
Public Sub C()
End Sub
Public Sub D()
End Sub
Public Sub E()
End Sub
Public Sub Test()
A()
On Error GoTo ErrorHandler
B()
Exit Sub
C()
ErrorHandler:
D()
Resume Next
E()
End Sub
компилирует (без дополнительных методов):
.method public static void Test() cil managed
{
// Code size 201 (0xc9)
.maxstack 3
.locals init (int32 V_0,
int32 V_1,
int32 V_2)
IL_0000: ldc.i4.1
IL_0001: stloc.2
IL_0002: call void VBTest.Program::A()
IL_0007: call void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::ClearProjectError()
IL_000c: ldc.i4.2
IL_000d: stloc.0
IL_000e: ldc.i4.3
IL_000f: stloc.2
IL_0010: call void VBTest.Program::B()
IL_0015: leave IL_00c0
IL_001a: ldc.i4.5
IL_001b: stloc.2
IL_001c: call void VBTest.Program::C()
IL_0021: ldc.i4.6
IL_0022: stloc.2
IL_0023: call void VBTest.Program::D()
IL_0028: ldc.i4.7
IL_0029: stloc.2
IL_002a: call void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::ClearProjectError()
IL_002f: ldloc.1
IL_0030: brtrue.s IL_0047
IL_0032: ldc.i4 0x800a0014
IL_0037: call class [mscorlib]System.Exception [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::CreateProjectError(int32)
IL_003c: throw
IL_003d: ldc.i4.s 9
IL_003f: stloc.2
IL_0040: call void VBTest.Program::E()
IL_0045: leave.s IL_00c0
IL_0047: ldloc.1
IL_0048: ldc.i4.1
IL_0049: add
IL_004a: ldc.i4.0
IL_004b: stloc.1
IL_004c: switch (
IL_007d,
IL_0000,
IL_0007,
IL_000e,
IL_0015,
IL_001a,
IL_0021,
IL_0028,
IL_003d,
IL_003d,
IL_0045)
IL_007d: leave.s IL_00b5
IL_007f: ldloc.2
IL_0080: stloc.1
IL_0081: ldloc.0
IL_0082: switch (
IL_0093,
IL_0047,
IL_0021)
IL_0093: leave.s IL_00b5
IL_0095: isinst [mscorlib]System.Exception
IL_009a: ldnull
IL_009b: cgt.un
IL_009d: ldloc.0
IL_009e: ldc.i4.0
IL_009f: cgt.un
IL_00a1: and
IL_00a2: ldloc.1
IL_00a3: ldc.i4.0
IL_00a4: ceq
IL_00a6: and
IL_00a7: endfilter
IL_00a9: castclass [mscorlib]System.Exception
IL_00ae: call void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::SetProjectError(class [mscorlib]System.Exception)
IL_00b3: leave.s IL_007f
IL_00b5: ldc.i4 0x800a0033
.try IL_0000 to IL_0095 filter IL_0095 handler IL_00a9 to IL_00b5
IL_00ba: call class [mscorlib]System.Exception [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::CreateProjectError(int32)
IL_00bf: throw
IL_00c0: ldloc.1
IL_00c1: brfalse.s IL_00c8
IL_00c3: call void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::ClearProjectError()
IL_00c8: ret
} // end of method Program::Test
Это неоднородности получают декомпилированы с отражателем на это:
public static void Test()
{
int num2;
try
{
int num3;
Label_0000:
num3 = 1;
A();
Label_0007:
ProjectData.ClearProjectError();
int num = 2;
Label_000E:
num3 = 3;
B();
goto Label_00C0;
Label_001A:
num3 = 5;
C();
Label_0021:
num3 = 6;
D();
Label_0028:
num3 = 7;
ProjectData.ClearProjectError();
if (num2 != 0)
{
goto Label_0047;
}
throw ProjectData.CreateProjectError(-2146828268);
Label_003D:
num3 = 9;
E();
goto Label_00C0;
Label_0047:
num2 = 0;
switch ((num2 + 1))
{
case 1:
goto Label_0000;
case 2:
goto Label_0007;
case 3:
goto Label_000E;
case 4:
case 10:
goto Label_00C0;
case 5:
goto Label_001A;
case 6:
goto Label_0021;
case 7:
goto Label_0028;
case 8:
case 9:
goto Label_003D;
default:
goto Label_00B5;
}
Label_007F:
num2 = num3;
switch (num)
{
case 0:
goto Label_00B5;
case 1:
goto Label_0047;
case 2:
goto Label_0021;
}
}
catch (object obj1) when (?)
{
ProjectData.SetProjectError((Exception) obj1);
goto Label_007F;
}
Label_00B5:
throw ProjectData.CreateProjectError(-2146828237);
Label_00C0:
if (num2 != 0)
{
ProjectData.ClearProjectError();
}
}
Помимо факт, что он использует кучу переключателей и gotos, я понятия не имею, что на самом деле делает этот код.
- 1. Application.OnTime on Error Resume Next
- 2. ruby "on error resume next" function
- 3. On Error Resume next not working VBA
- 4. C# On Error resume
- 5. VBA: Как долго работает On Error Resume Next?
- 6. Excel VBA On Error Resume Next Возвращает значение вне позиции
- 7. on error resume next дает неправильный результат при вставке изображений
- 8. Что такое лучшая альтернатива «On Error Resume Next» для C#?
- 9. Что означает эквивалент vb's On Error Resume Next в Java?
- 10. Visual Basic's On Error Resume Next для C++?
- 11. Использование On Error Resume Next with If statement
- 12. Что означает «on error goto 0» и «error resume next» в старом ASP?
- 13. SQL Server 'Resume Next' Equivalent
- 14. VBA Error Handling RESUME
- 15. On Error Resume Next не работает в VBScript (VBS) при установке объекта
- 16. On Error Resume Next не перехватывает ошибки SQL-сервера в VBScript
- 17. Если мы сталкиваемся с несколькими ошибками при использовании On Error Resume Next
- 18. PhantomJS - pause/resume Выполнение javascript
- 19. On Error GoTo in loop with 2x next (1x on error, 1x on normal procedure)
- 20. Count Down Timer on Resume
- 21. Flexslider resume slideshow on mouseover
- 22. Fixing Next Without For Error
- 23. Add Pause/Resume Button on Cycle
- 24. jquery validate collapsible expand on next error message
- 25. Array Out Of Bounds Error on Next Bit String Algorithm
- 26. jQuery resume setInterval timer on нажатие клавиши
- 27. PhoneGap/Cordova blank screen on pause/resume
- 28. Ошибка ANR с libgdx on pause/resume
- 29. Next for For compile error
- 30. Loop Error (Next for For)