Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TargetException thrown while using reflection to add an event handler

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

The exception message is

Object does not match target type.

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.]

like image 810
awj Avatar asked Mar 23 '26 02:03

awj


1 Answers

You are passing this incorrectly:

addHandler.Invoke(this, addHandlerArgs);

The object with the event is not this (although 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;

Or at least use EventInfo.AddEventHandler.

like image 127
Marc Gravell Avatar answered Mar 24 '26 19:03

Marc Gravell



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!