3

WebClient オブジェクトがコールバックしたときに BackgroundWorker スレッドを呼び出したいと考えています。

この BackgroundWorker で実行するメソッドは固定されていないため、指定されたメソッドをプログラムでターゲットにする必要があります。

これを実現するには: WebClient に渡されるイベント args オブジェクトのプロパティの 1 つは、どのメソッドを取得する必要があるかを詳しく説明します (e.UserState.ToString())。このメソッド期待どおりに取得されています。

次に、この取得したメソッドを BackgroundWorker.DoWork イベントのデリゲートとして追加したいと考えています。

// this line gets the targeted delegate method from the method name
var method = GetType().GetMethod(e.UserState.ToString(), BindingFlags.NonPublic | BindingFlags.Instance);
if (method != null)
{
    // get the DoWork delegate on the BackgroundWorker object
    var eventDoWork = _bw.GetType().GetEvent("DoWork", BindingFlags.Public | BindingFlags.Instance);
    var tDelegate = eventDoWork.EventHandlerType;
    var d = Delegate.CreateDelegate(tDelegate, this, method);

    // add the targeted method as a handler for the DoWork event
    var addHandler = eventDoWork.GetAddMethod(false);
    Object[] addHandlerArgs = { d };
    addHandler.Invoke(this, addHandlerArgs);

    // now invoke the targeted method on the BackgroundWorker thread
    if (_bw.IsBusy != true)
    {
        _bw.RunWorkerAsync(e);
    }
}

何らかの理由で TargetException が行にスローされます

addHandler.Invoke(this, addHandlerArgs);

例外メッセージは

オブジェクトがターゲット タイプと一致しません。

私がコードを構築しているメソッドのシグネチャは

private void GotQueueAsync(object sender, DoWorkEventArgs e)

これは、BackgroundWorker.DoWork イベント ハンドラーの署名と一致します。

私が何を間違えたのか、またはこのハンドラーメソッドをプログラムで追加できない理由を誰かに説明してもらえますか?

[念のため、これは WP7 アプリです。]

4

1 に答える 1

5

thisあなたは間違って渡しています:

addHandler.Invoke(this, addHandlerArgs);

イベントを持つオブジェクトはそうではありませんthis(thisハンドラーはありますが) - 次のようにする必要があります_bw

addHandler.Invoke(_bw, addHandlerArgs);

ただし、より簡単には:

var d = (DoWorkEventHandler)Delegate.CreateDelegate(
    typeof(DoWorkEventHandler), this, method);
_bw.DoWork += d;

または、少なくとも使用しますEventInfo.AddEventHandler

于 2012-07-28T19:35:54.763 に答える