c# .Net CF Form.Invoke 引发 ArgumentException

标签 c# events compact-framework user-interface invoke

我从以下代码中收到一个 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);
} 

感谢您抽出时间来看

最佳答案

来自Msdn article关于事件:

Events are a special kind of multicast delegate that can only be invoked from within the class or struct where they are declared (the publisher class).

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

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

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

关于c# .Net CF Form.Invoke 引发 ArgumentException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1226680/

相关文章:

c# - TreeView私有(private)变量清除

c# - IQueryable 和模型绑定(bind)魔术?

c# - 在 C#3 和 C#4 中是否有更简洁的方法来定义自定义事件?

oop - VB6 实现和事件

c# - Hook API 函数 GetSystemMetrics

c# - 如何使用 await 简单安全地调用可为空的委托(delegate)

c# - 将额外参数传递给委托(delegate)

sql-server - 如何导入 SDF 文件

c# - 数组作为 DataGrid 的数据源 : how to customize columns?

c# - 您如何使用 .net 2.0 中的 WebBrowser 控件检查 ajax 更新?