动态IL方法使"手术可能会破坏运行" [英] Dynamic IL method causes "Operation could destabilize the runtime"

查看:224
本文介绍了动态IL方法使"手术可能会破坏运行"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


System.Security.VerificationException:
操作可能会破坏
运行。在Connance.CommunicatorApi.ReportApiClient.AcknowledgeRecallsAsyncDynamicHandler
(对象
,AcknowledgeRecallsCompletedEventArgs




这就是错误我得到。我试图做(背景)是创建一个全局事件处理的一类方法。我用静态代理在WCF工作,我需要建立跟踪所有的调用和返回所有的WCF Web方法层。不幸的是,WCF强类型已完成事件的EventArgs,使得它几乎是不可能的。



我决定尝试一些东西。如果事件是事件处理程序和LT; SomeSpecificEventArgs> ,我依然可以注册签名 void方法(对象,对象)的方法处理该事件。大。所以我掀起来创建一个 DynamicMethod的这会打电话给我的全球的处理程序,并将其注册到每个事件。



我尝试了两种方式:




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



2)类型为void(对象,
SomeSpecificEventArgs) - 我使用这个
泛型方法来获取




只是,当我尝试调用该方法,可以手动或事件,我得到了上面的异常。



下面是我的代码:

  //的所有回调处理程序。 
//在本例中它什么都不做。
公共无效处理程序(对象发件人,对象E)
{
动态evtArgs = E;
对象userState = evtArgs.UserState;
}

私人字符串则getIdentifier(代表D)
{
返回string.Concat(d.Method.DeclaringType,'。',d.Method.Name) ;
}

//方法注册的事件处理程序
公共无效注册< T> (代表O),其中T:EventArgs的
{
//获取一些信息
/ *剪断。代码以获取方法的名称,并计算事件* /

VAR eventInst = ownerType.GetEvent(eventName的)的名称;

//下面的作品,例如:
// someObj.MethodCompleted + =处理程序;
//即使MethodCompleted是EventHandler类型和LT的事件; SomeSpecialEventArgs>

//获取实际的类型处理器
变种handlerType = eventInst.EventHandlerType;
事件处理evtHandler =新的EventHandler(处理程序);

DynamicMethod的DM =新的DynamicMethod的(
则getIdentifier(O)+DynamicHandler,//设置名称
的typeof(无效),//返回void
新[] {typeof运算(对象)的typeof(T)}); // params对象和事件参数

的ILGenerator根= dm.GetILGenerator的类型();

gen.Emit(OpCodes.Ldarg_0); //加载第一个参数堆栈调用
gen.Emit(OpCodes.Ldarg_2); //加载第二个参数堆栈调用

gen.Emit(OpCodes.Call,evtHandler.Method); //调用方法

gen.Emit(OpCodes.Ret); //返回

//这是最后代表
变种superdlg = dm.CreateDelegate(handlerType);

//问题众生这里:
//当事件引发和委托调用
//如果我dynamicInvoke它,我得到的错误
eventInst.AddEventHandler(ownerInst,superdlg);
}



编辑:
我明白了。事实证明,我有另外一个问题。我在Silverlight中工作。我设法复制我的方案在一个单独的项目,我把它用 DynamicMethod的的过载,它允许您设置一个所有者工作。那么我指定



DynamicMethod的DM =新的DynamicMethod的(TestMethod2的typeof(无效),新[] {typeof运算(MyClass的)的typeof(字符串),typeof运算(字符串)}的typeof(MyClass的));



和使用 ldarg.0 ldarg.1 ldarg.2 。但是,这是一个安全的关键构造,不会对Silverlight的运行。我只是不知道我是如何设置它呢。难道我让处理程序公共静态和负载ARGS 0-1?我最终得到一个错误这样的:




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



解决方案

好了,我想出了这一点。



请在处理程序方法的实例方法,并添加了对拥有它的类的类型的 DynamicMethod的构造另一个参数类型(隐含的这个参数)。



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


System.Security.VerificationException: Operation could destabilize the runtime. at Connance.CommunicatorApi.ReportApiClient.AcknowledgeRecallsAsyncDynamicHandler(Object , AcknowledgeRecallsCompletedEventArgs )

That's the error I'm getting. What I'm trying to do (background) is create a global event handler for a class of methods. I'm working with a Static Proxy in WCF and I need to create a layer which tracks all the calls and returns to all of the WCF web methods. Unfortunately, WCF strongly types the "Completed" events' EventArgs, making it nearly impossible.

I decided to try something. If an event is EventHandler<SomeSpecificEventArgs>, I can still register a method of signature void Method(object, object) to handle the event. Great. So I set off to create a DynamicMethod which would call my global handler, and register it to each event.

I tried two ways:

1) DynamicMethod is of type void (object, object)

2) of type void (object, SomeSpecificEventArgs) -- I use a generic method for this to get the type.

Only, when I try to invoke the method, either manually or for the event, I get the above exception.

Here's my code:

    // 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<T> (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<SomeSpecialEventArgs>

    // 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);
}

edit: I see. It turns out I have another issue. I'm working in Silverlight. I managed to reproduce my scenario in a separate project and I got it working by using the overload of DynamicMethod which allows you to set an owner. I then specify

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

and use ldarg.0, ldarg.1, and ldarg.2. But this is a security critical constructor and won't run on silverlight. I'm just not sure how I need to set it up then. Do I make the Handler public static and load args 0-1? I end up getting an error like this:

Attempt by method 'DynamicClass.TestMethod2(System.String, System.String)' to access method 'dynamicass.MyClass.Handler(System.String, System.String)' failed."}

解决方案

Ok, so what I came up was with this.

Make the Handler method an instance method, and add another argument type for the DynamicMethod constructor of the type of the class that owns it (for the implicit this argument).

then you do dm.CreateDelegate(_args_, this)

这篇关于动态IL方法使&QUOT;手术可能会破坏运行&QUOT;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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