4

System.Security.VerificationException: 操作により、ランタイムが不安定になる可能性があります。Connance.CommunicatorApi.ReportApiClient.AcknowledgeRecallsAsyncDynamicHandler (オブジェクト、AcknowledgeRecallsCompletedEventArgs) で

それが私が得ているエラーです。私がやろうとしていること (背景) は、メソッドのクラスのグローバル イベント ハンドラーを作成することです。私は WCF で静的プロキシを使用しています。すべての呼び出しを追跡し、すべての WCF Web メソッドに戻るレイヤーを作成する必要があります。残念ながら、WCF は "Completed" イベントの EventArgs を厳密に型指定するため、ほとんど不可能です。

私は何かを試してみることにしました。イベントが の場合でも、イベントを処理するEventHandler<SomeSpecificEventArgs>署名の方法を登録できます。void Method(object, object)偉大な。そこで、グローバルハンドラDynamicMethodを呼び出すを作成し、それを各イベントに登録することにしました。

私は2つの方法を試しました:

1) DynamicMethod は void (オブジェクト、オブジェクト) 型です

2) 型 void (object, SomeSpecificEventArgs) -- 汎用メソッドを使用して型を取得します。

手動またはイベントのためにメソッドを呼び出そうとすると、上記の例外が発生します。

これが私のコードです:

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

編集:なるほど。別の問題があることがわかりました。私はシルバーライトで作業しています。別のプロジェクトでシナリオを再現するDynamicMethodことができ、所有者を設定できるオーバーロードを使用して動作させました。次に指定します

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

ldarg.0ldarg.1、および を使用しldarg.2ます。ただし、これはセキュリティ クリティカルなコンストラクターであり、Silverlight では実行されません。その場合、どのように設定する必要があるのか​​ わかりません。public を staticにして、Handlerargs を 0 ~ 1 にロードしますか? 次のようなエラーが発生します。

メソッド「DynamicClass.TestMethod2(System.String, System.String)」によるメソッド「dynamicass.MyClass.Handler(System.String, System.String)」へのアクセスに失敗しました。"}

4

2 に答える 2

4

メソッド引数のインデックスは 0 です - and の代わりに and を使用ldarg.0ldarg.1ldarg.1くださいldarg.2

イベント ハンドラー メソッドの呼び出しにも問題があります。thisメソッドのポインターを指定していません ( Delegate.Target)。this登録されているものに応じて、静的である場合とそうでない場合があるポインターを提供する必要があります。

これは、マルチキャスト デリゲートも処理しません。これは、イベントに登録されたハンドラーの 1 つだけを呼び出します。あなたがする必要があるのは、次のようなメソッドを生成することです:

.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メソッドを使用します。

于 2011-03-16T12:04:26.953 に答える
0

さて、私が思いついたのはこれでした。

メソッドHandlerをインスタンスメソッドにし、DynamicMethodそれを所有するクラスの型のコンストラクター用に別の引数型を追加します(暗黙のthis引数用)。

その後、あなたはしますdm.CreateDelegate(_args_, this)

于 2011-03-16T19:28:29.797 に答える