简体   繁体   English

C#.Net CF Form.Invoke引发ArgumentException

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

I am receving an ArgumentException from the following code, I am struggling to understand it the last entry in the stack trace is 我正在从以下代码中获取ArgumentException,我正在努力理解它,堆栈跟踪中的最后一项是

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

When I step through the DeviceResponse is populated as I expect and the target is located and as expected but the targetForm.Invoke throws everytime 当我逐步执行DeviceResponse时,将按我的预期进行填充,并且按预期方式定位了目标,但是targetForm.Invoke每次都会抛出

Any help would be much appreciated. 任何帮助将非常感激。

The event is defined as: 该事件定义为:

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

The event is being raised from this code: 该事件从以下代码引发:

//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));
    }
}

The MsgEventArgs is a generic event arguments class deriving from EventArgs: 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; }
    }
}

In my form I have registered for the event in the forms constructor: 在我的表单中,我已经在表单构造函数中注册了该事件:

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

With the implementation as: 与实现为:

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

Thanks for taking the time to have a look 感谢您抽出宝贵时间来看看

From the Msdn article on events: 从有关事件的Msdn文章中:

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). 事件是一种特殊的多播委托,只能在声明它们的类或结构(发布者类)中调用。

This makes sense. 这是有道理的。 The class that declares the event (publisher) should be the only one who determines when and where the event is raised. 声明事件的类(发布者)应该是唯一确定何时何地引发事件的类。 This is also why event exposes only certain operations to client code (subscriber) such as subscribe and unsubcribe. 这也是为什么事件仅向客户端代码(订户)公开某些操作的原因,例如订阅和取消订阅。

In your code, you're passing DeviceResponseReceived event as a delegate argument in targetForm.Invoke and expecting it to be invoked by the target (Form). 在您的代码中,您将DeviceResponseReceived事件作为targetForm.Invoke中的委托参数传递,并期望由目标(Form)调用。 Target is not where the event is declared hence the exception. 目标不在声明事件的位置,因此是异常。

You want to ensure that DeviceResponse_DeviceResponseReceived event handler is executed on the UI thread since it is propably touching the UI components. 您要确保DeviceResponse_DeviceResponseReceived事件处理程序在UI线程上执行,因为它正好接触UI组件。 Then in there you can check if InvokeRequired . 然后在那里可以检查InvokeRequired是否 Check out WinForms UI Thread Invokes for more information on how to update UI from other threads. 有关如何从其他线程更新UI的更多信息,请参见WinForms UI线程调用

Without having tried the code out, one thing strikes me as odd in the following code: 在没有尝试代码的情况下,以下代码使我感到奇怪:

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));
    }
}

You check if the DeviceResponseReceived delegate (I assume it is?) is assigned, and then you tell targetForm to invoke that delegate. 您检查是否已分配DeviceResponseReceived委托(我想是吗?),然后告诉targetForm调用该委托。 Where is the delegate actually pointing to? 代表实际指向哪里? I would guess that what you really want to do is to invoke the corresponding method in targetForm ? 我猜想您真正想做的是在targetForm调用相应的方法?

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

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