繁体   English   中英

C#.Net CF Form.Invoke引发ArgumentException

[英]c# .Net CF Form.Invoke raise ArgumentException

我正在从以下代码中获取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文章中:

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

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

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

您要确保DeviceResponse_DeviceResponseReceived事件处理程序在UI线程上执行,因为它正好接触UI组件。 然后在那里可以检查InvokeRequired是否 有关如何从其他线程更新UI的更多信息,请参见WinForms UI线程调用

在没有尝试代码的情况下,以下代码使我感到奇怪:

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调用相应的方法?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM