1

我正在从以下代码中收到 ArgumentException,我很难理解它堆栈跟踪中的最后一个条目是

System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr,
                Binder binder, Object[] parameters, CultureInfo culture, 
                Boolean verifyAccess, StackCrawlMark& stackMark)

当我逐步完成 DeviceResponse 时,按预期填充,并且目标已按预期定位,但 targetForm.Invoke 每次都会抛出

任何帮助将非常感激。

事件定义为:

public static event EventHandler<MsgEventArgs<DeviceResponse>> DeviceResponseReceived;

该事件正在从此代码中引发:

//Raise the event
if (DeviceResponseReceived != null)
{
    if (DeviceResponseReceived.Target is System.Windows.Forms.Form)
    {
         System.Windows.Forms.Form targetForm = DeviceResponseReceived.Target as System.Windows.Forms.Form;
         targetForm.Invoke(DeviceResponseReceived, new MsgEventArgs<DeviceResponse>(deviceResponse));
    }
}

MsgEventArgs 是派生自 EventArgs 的通用事件参数类:

public class MsgEventArgs<T> : EventArgs
{
    public MsgEventArgs(T value)
    {
        m_value = value;
    }
    private T m_value;
    public T Value
    {
        get { return m_value; }
    }
}

在我的表单中,我已经在表单构造函数中注册了该事件:

DeviceResponse.DeviceResponseReceived += new EventHandler<MIASmartClient.Messaging.Transport.MsgEventArgs<DeviceResponse>>(DeviceResponse_DeviceResponseReceived);

实施为:

void DeviceResponse_DeviceResponseReceived(object sender, MIASmartClient.Messaging.Transport.MsgEventArgs<DeviceResponse> e)
{
    _presenter.DeviceResponseReceived(e.Value);
} 

感谢您花时间看一看

4

2 回答 2

5

来自Msdn关于事件的文章:

事件是一种特殊的多播委托,只能从声明它们的类或结构(发布者类)中调用。

这是有道理的。声明事件的类(发布者)应该是唯一确定引发事件的时间和地点的类。这也是为什么事件只向客户端代码(订阅者)公开某些操作,例如订阅和取消订阅。

在您的代码中,您将 DeviceResponseReceived 事件作为 targetForm.Invoke 中的委托参数传递,并期望它被目标 (Form) 调用。目标不是声明事件的位置,因此是异常。

您希望确保在 UI 线程上执行 DeviceResponse_DeviceResponseReceived 事件处理程序,因为它可能会接触 UI 组件。然后在那里你可以检查是否InvokeRequired。查看WinForms UI 线程调用以获取有关如何从其他线程更新 UI 的更多信息。

于 2009-08-04T11:36:35.220 回答
0

在没有尝试过代码的情况下,以下代码中的一件事让我觉得很奇怪:

if (DeviceResponseReceived != null)
{
    if (DeviceResponseReceived.Target is System.Windows.Forms.Form)
    {
         System.Windows.Forms.Form targetForm = DeviceResponseReceived.Target as System.Windows.Forms.Form;
         targetForm.Invoke(DeviceResponseReceived, new MsgEventArgs<DeviceResponse>(deviceResponse));
    }
}

您检查是否DeviceResponseReceived分配了委托(我假设是?),然后告诉targetForm调用该委托。代表实际上指向哪里?我猜你真正想做的是在 ? 中调用相应的方法targetForm

于 2009-08-04T10:35:09.710 回答