TargetException lanzada al usar la reflexión para agregar un controlador de eventos

I want to invoke a BackgroundWorker thread when a WebClient object calls back.

The method which I target to run on this BackgroundWorker is not fixed so I need to programmatically target a specified method.

To achieve this: One of the properties on the event args object passed to the WebClient details which method should be obtained (e.UserState.ToString()). This method is being obtained as expected.

What I then hope to do is add this obtained method as a delegate on the BackgroundWorker.DoWork event.

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

For some reason a TargetException is thrown on the line

addHandler.Invoke(this, addHandlerArgs);

El mensaje de excepción es

El objeto no coincide con el tipo de destino.

The signature of the method which I'm building the code around is

private void GotQueueAsync(object sender, DoWorkEventArgs e)

This matches the signature for a BackgroundWorker.DoWork event handler.

Can anyone explain to me what I've done wrong or why I'm unable to programmatically add this handler method.

[In case it matters, this is a WP7 app.]

preguntado el 28 de julio de 12 a las 20:07

1 Respuestas

Estas pasando this incorrectamente:

addHandler.Invoke(this, addHandlerArgs);

The object with the event is not this (a pesar de que this has the handler) - it should be _bw:

addHandler.Invoke(_bw, addHandlerArgs);

More simply, though:

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

O al menos usar EventInfo.AddEventHandler.

Respondido 28 Jul 12, 20:07

Yes, both suggestions work perfectly. That's saved me a lot of head-scratching. Thanks. - awj

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.