3

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

我在此 BackgroundWorker 上运行的目标方法不固定,因此我需要以编程方式定位指定的方法。

为实现这一点:传递给 WebClient 的事件 args 对象的属性之一详细说明了应获取的方法(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 回答