c# – Reflection.Emit.ILGenerator异常处理“Leave”指令
首先,一些背景信息:
我正在为一个学校项目编写一个编译器.它已经在运行,我花费了大量的精力来修复和/或优化它.最近遇到一个问题是我发现当您调用以下任何成员方法时,ILGenerator对象会生成一个额外的休假指令: BeginCatchBlock() BeginExceptFilterBlock() BeginFaultBlock() BeginFinallyBlock() EndExceptionBlock() 所以,通过调用BeginExceptionBlock()来启动一个try语句,用BeginCatchBlock()添加一些catch子句,可以用BeginFinallyBlock()添加一个finally子句,然后用EndExceptionBlock()结束受保护的代码区域. 我列出的方法自动生成一条在try语句之后分支到第一条指令的leave指令.我不想要这些,有两个原因.一个,因为它总是生成一个未优化的休假指令,而不是一个leave.s指令,即使它的分支只有两个字节.另外两个,因为你不能控制休假指令的位置. 所以,如果你想分支到你的代码中的其他位置,你必须添加一个编译器生成的本地变量,根据你想要进入try语句的位置来设置它,让EndExceptionBlock()自动生成leave指令,然后在try块下面生成一个switch语句.或者,您可以在调用之前的方法之前自己发出leave或leave.s指令,导致一个丑陋和不可访问的额外5个字节,如下所示: L_00ca: leave.s L_00e5 L_00cc: leave L_00d1 这两个选项都是我不能接受的.有没有办法阻止自动生成假指示,还是以其他方式指定保护区,而不是使用这些方法(这是非常烦人的,实际上没有记录的)? 编辑 public static async Task<bool> TestAsync(int ms) { var local = ms / 1000; Console.WriteLine("In async call,before await " + local.ToString() + "-second delay."); await System.Threading.Tasks.Task.Delay(ms); Console.WriteLine("In async call,after await " + local.ToString() + "-second delay."); Console.WriteLine(); Console.WriteLine("Press any key to continue."); Console.ReadKey(false); return true; } 解决方法
据我所知,您无法在.NET 4.0中执行此操作.使用ILGenerator创建方法体的唯一方法是使用MethodBuilder.CreateMethodBody,但不允许您设置异常处理信息.而ILGenerator强制您所要求的休假指示.
但是,如果.NET 4.5是您的选项(似乎是),请查看 当然,总是有Mono.Cecil,但是这可能需要对您已经编写的代码进行更广泛的更改. 编辑:you appear to have already figured this out yourself,但是你把这个问题放开了.您可以发布自己的问题的答案,并接受他们,如果你自己弄清楚了.这样可以让我知道我不应该浪费时间搜寻,而让其他同样问题的人知道该怎么做. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |