动态IL方法导致“操作可能破坏运行时的稳定性”

System.Security.VerificationException:操作可能会破坏运行时的稳定性。 在Connance.CommunicatorApi.ReportApiClient.AcknowledgeRecallsAsyncDynamicHandler(Object,AcknowledgeRecallsCompletedEventArgs)

那是我得到的错误。 我正在尝试做的(背景)是为一类方法创建一个全局事件处理程序。 我正在使用WCF中的静态代理,我需要创建一个跟踪所有调用并返回所有WCF Web方法的层。 不幸的是,WCF强烈地键入了“已完成”事件的EventArgs,几乎不可能。

我决定尝试一下。 如果事件是EventHandler ,我仍然可以注册签名void Method(object, object)来处理事件。 大。 所以我开始创建一个DynamicMethod ,它将调用我的全局处理程序,并将其注册到每个事件。

我试过两种方法:

1)DynamicMethod的类型为void(对象,对象)

2)类型为void(object,SomeSpecificEventArgs) – 我使用generics方法来获取类型。

只有当我尝试手动或为事件调用方法时,我才得到上述exception。

这是我的代码:

  // The handler for all callbacks. // in the example it does nothing. public void Handler(object sender, object e) { dynamic evtArgs = e; object userState = evtArgs.UserState; } private string GetIdentifier(Delegate d) { return string.Concat(d.Method.DeclaringType, '.', d.Method.Name); } // Method to register an event handler public void Register (Delegate o) where T : EventArgs { // get some info /* snip. code to get method name, and calculate name of event */ var eventInst = ownerType.GetEvent(eventName); // The following works, for example: // someObj.MethodCompleted += Handler; // even though MethodCompleted is an event of type EventHandler // get the actual type of handler var handlerType = eventInst.EventHandlerType; EventHandler evtHandler = new EventHandler(Handler); DynamicMethod dm = new DynamicMethod( GetIdentifier(o) + "DynamicHandler", // set the name typeof(void), // return void new[] { typeof(object), typeof(T) });// params object and type of event args ILGenerator gen = dm.GetILGenerator(); gen.Emit(OpCodes.Ldarg_0); // load first arg to stack for calling gen.Emit(OpCodes.Ldarg_2); // load second arg to stack for calling gen.Emit(OpCodes.Call, evtHandler.Method); // call method gen.Emit(OpCodes.Ret); // return // this is the final delegate var superdlg = dm.CreateDelegate(handlerType); // the problem beings here: // when the event is raised and the delegate is invoked // of if I dynamicInvoke it, I get the error eventInst.AddEventHandler(ownerInst, superdlg); } 

编辑:我明白了。 事实certificate我有另一个问题。 我在Silverlight工作。 我设法在一个单独的项目中重现我的场景,并通过使用DynamicMethod的重载来DynamicMethod它,它允许您设置所有者。 然后我指定

DynamicMethod dm = new DynamicMethod("TestMethod2", typeof(void), new[] { typeof(MyClass), typeof(string), typeof(string) }, typeof(MyClass));

并使用ldarg.0ldarg.1ldarg.2 。 但这是一个安全关键的构造函数,不会在Silverlight上运行。 我只是不确定我需要如何设置它。 我是否将Handler公共静态并加载args 0-1? 我最终得到这样的错误:

尝试通过方法’DynamicClass.TestMethod2(System.String,System.String)’来访问方法’dynamicass.MyClass.Handler(System.String,System.String)’失败。“}

方法参数为零索引 – 使用ldarg.0ldarg.1而不是ldarg.1ldarg.2

调用事件处理程序方法也存在问题 – 您没有为方法指定this指针( Delegate.Target )。 您需要提供一个this指针,根据注册的内容,它可能是静态的,也可能不是静态的。

这也不会处理多播委托 – 这只会调用在事件上注册的处理程序之一。 你需要做的是产生这样的方法:

 .method public static CallEventHandler(EventHandlerType ev, object sender, EventArgsType e) { ldarg.0 // the Invoke 'this' pointer ldarg.1 ldarg.2 callvirt instance void EventHandlerType::Invoke(object, EventArgsType) ret } 

这使用事件的Invoke方法,该方法处理为您调用所有已注册的处理程序。

好的,所以我提出的就是这个。

使Handler方法成为实例方法,并为拥有它的类的类型的DynamicMethod构造函数添加另一个参数类型(对于隐式this参数)。

然后你做dm.CreateDelegate(_args_, this)