使用反射添加事件处理程序时抛出TargetException

时间:2012-07-28 19:27:37

标签: .net reflection asynchronous delegates backgroundworker

我想在WebClient对象回调时调用BackgroundWorker线程。

我定位在此BackgroundWorker上运行的方法未修复,因此我需要以编程方式定位指定的方法。

要实现这个目标: 事件args对象的一个​​属性传递给WebClient详细信息应该获取哪个方法(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应用程序。]

1 个答案:

答案 0 :(得分: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