如何抓关键词确定异常抛出的类型? [英] How does the catch keyword determine the type of exception that was thrown?

查看:146
本文介绍了如何抓关键词确定异常抛出的类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在关键字确定异常抛出的类型?出现什么样的流程来选择要执行的catch块?

How does the catch keyword determine the type of exception that was thrown? What process occurs to select which catch block to execute?

try
{
    int[] myArray = new int[0];
    myArray[1] = 0;
}
catch (IndexOutOfRangeException ex) { } // how does the CLR know to enter here?
catch (InvalidCastException ex) { }

通过反汇编

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       28 (0x1c)
  .maxstack  3
  .locals init (int32[] V_0,
           class [mscorlib]System.IndexOutOfRangeException V_1,
           class [mscorlib]System.InvalidCastException V_2)
  IL_0000:  nop
  .try
  {
    IL_0001:  nop
    IL_0002:  ldc.i4.0
    IL_0003:  newarr     [mscorlib]System.Int32
    IL_0008:  stloc.0
    IL_0009:  ldloc.0
    IL_000a:  ldc.i4.1
    IL_000b:  ldc.i4.0
    IL_000c:  stelem.i4
    IL_000d:  nop
    IL_000e:  leave.s    IL_001a
  }  // end .try
  catch [mscorlib]System.IndexOutOfRangeException 
  {
    IL_0010:  stloc.1
    IL_0011:  nop
    IL_0012:  nop
    IL_0013:  leave.s    IL_001a
  }  // end handler
  catch [mscorlib]System.InvalidCastException 
  {
    IL_0015:  stloc.2
    IL_0016:  nop
    IL_0017:  nop
    IL_0018:  leave.s    IL_001a
  }  // end handler
  IL_001a:  nop
  IL_001b:  ret
 } // end of method Program::Main

不过,目前还不清楚是什么关键字做,以确定被抛出该异常的类型。

But it is still not clear what the catch keyword does in order to determine the type of exception that was thrown.

推荐答案

只是一个简单的答案,一个真正的需要的书。异常处理的.NET是可笑复杂,涉及到许多移动部件。包括例外在Windows(SEH,结构化异常处理)时,code中的最大和最复杂的区块之一的原生支持,在CLR(excep.cpp,232KB的code),元数据的组件(这就是为什么你没有看到它采取任何IL地址)和抖动。

Just a short answer, a real one requires a book. Exception handling in .NET is ridiculously complicated, involving many moving parts. Including the native support for exceptions in Windows (SEH, Structured Exception Handling), one of the largest and most complicated chunks of code in the CLR (excep.cpp, 232KB of code), metadata in the assembly (which is why you don't see it taking any IL addresses) and the jitter.

异常是由抛出的关键字提高后,触发中的RaiseException()Windows API函数在运行时。窗户去寻找code,它是愿意通过运行异常过滤器,通过RtlAddFunctionTable注册()来处理异常。这是在CLR的实现。它轮流使用这些受抖动产生的元数据,这是建立在数据表只是即时编译时抖动IL转换为机器code。抖动使用已添加到程序集元数据通过指令一样。尝试和捕捉,你在拆卸看的元数据信息。该表中的数据有什么范围code再presents为特定的异常类型的catch子句信息。让CLR选择一个位置,执行应当恢复并告​​诉Windows与处理异常继续前进。

Exceptions are raised by the throw keyword, it triggers the RaiseException() Windows api function at runtime. Windows goes looking for code that's willing to handle the exception by running exception filters, registered by RtlAddFunctionTable(). Which are implemented in the CLR. It in turns uses metadata that's generated by the jitter, tables of data that are built at just-in-time compile time when the jitter converts IL to machine code. The jitter uses the metadata info that was added to the assembly metadata by directives like .try and catch, what you see in the disassembly. The table data has info about what range of code represents the catch clause for a particular exception type. Allowing the CLR to pick a location where execution should resume and tell Windows to move on with handling the exception.

知道在那里开始了,知道在哪里停止,Windows现在开始展开堆栈帧,调用finally块必要。接下来,指令指针将其设置在catch块的第一台机器code指令。

Knowing where it started and knowing where to stop, Windows now starts unwinding stack frames, calling finally blocks where necessary. Next, the instruction pointer it set at the first machine code instruction of the catch block.

很多很多的超越这个讨厌的小细节。像ThreadAbortException,在vb.net抓住关键字时,finally块引发异常,用try块范围时务SEH是基于纯粹的堆栈帧的并发症,中止不可捕获的异常的概念,当线程需要的语义。这需要一本书,但没有人会写一个,因为读者会立刻睡着了的东西。

Lots and lots of nasty little details beyond this. Like the semantics of ThreadAbortException, the vb.net Catch When keyword, the complication of finally blocks raising exceptions, dealing with try blocks scope when SEH is purely stack frame based, the notion of uncatchable exceptions when threads need to be aborted. The stuff that takes a book but nobody will ever write one because the reader will instantly fall asleep.

异常处理的.NET是一个充满铅冰山。 99%是在水,的的最成功的CLR抽象之一。除了使用抓关键字过于频繁,但是这并没有什么关系呢实施方式的程序员。

Exception handling in .NET is an iceberg filled with lead. 99% is under water, one of the most successful abstractions in the CLR. Other than programmers using the catch keyword too often, that however doesn't have anything to do with the way it was implemented.

这篇关于如何抓关键词确定异常抛出的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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