Dev*_*low 1 c# events user-interface compact-framework invoke
我从以下代码接收ArgumentException,我很难理解堆栈跟踪中的最后一个条目是
System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr,
Binder binder, Object[] parameters, CultureInfo culture,
Boolean verifyAccess, StackCrawlMark& stackMark)
Run Code Online (Sandbox Code Playgroud)
当我逐步完成DeviceResponse时,按照我的预期填充并且目标位于并且符合预期,但每次都会抛出targetForm.Invoke
任何帮助将非常感激.
该事件定义为:
public static event EventHandler<MsgEventArgs<DeviceResponse>> DeviceResponseReceived;
Run Code Online (Sandbox Code Playgroud)
该代码正在引发该事件:
//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));
}
}
Run Code Online (Sandbox Code Playgroud)
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; }
}
}
Run Code Online (Sandbox Code Playgroud)
在我的表单中,我已在表单构造函数中注册了该事件:
DeviceResponse.DeviceResponseReceived += new EventHandler<MIASmartClient.Messaging.Transport.MsgEventArgs<DeviceResponse>>(DeviceResponse_DeviceResponseReceived);
Run Code Online (Sandbox Code Playgroud)
随着实施:
void DeviceResponse_DeviceResponseReceived(object sender, MIASmartClient.Messaging.Transport.MsgEventArgs<DeviceResponse> e)
{
_presenter.DeviceResponseReceived(e.Value);
}
Run Code Online (Sandbox Code Playgroud)
感谢您抽出宝贵时间来了解一下
事件是一种特殊的多播委托,只能从声明它们的类或结构(发布者类)中调用.
这是有道理的.声明事件(发布者)的类应该是唯一确定引发事件的时间和位置的类.这也是事件仅向客户端代码(订阅者)公开某些操作(如订阅和取消订阅)的原因.
在您的代码中,您将DeviceResponseReceived事件作为targetForm.Invoke中的委托参数传递,并期望它由目标(Form)调用.Target不是声明事件的位置,因此是异常.
您希望确保在UI线程上执行DeviceResponse_DeviceResponseReceived事件处理程序,因为它可以触及UI组件.然后在那里你可以检查是否InvokeRequired.有关如何从其他线程更新UI的更多信息,请查看WinForms UI线程调用.