【发布时间】:2015-02-03 18:58:46
【问题描述】:
我收到InvalidCastException 在以前有效的代码中将 EventHandler`1 转换为 EventHandler 并且我知道没有相关更改。 (我有新旧版本。)
有趣的是我一直在使用这种类型。 我不明白为什么 EventHandler`1 会扩展到 EventHandler。 请参阅随附的源代码摘录:
基础是这样的:
Option Strict On
Option Explicit On
Option Infer Off
Public Class CapturedEventArgs
Inherits EventArgs
Property Handled As Boolean
Property Processor As clsScannerProcessor
Property Scan As String
End Class
Public Class clsScannerProcessor
Public Event CapturedInProcessor As EventHandler(Of CapturedEventArgs)
'executed in background thread
Sub EvaluateScan()
'excerpt: ... on valid scan pattern
Dim cea As New CapturedEventArgs() With {.Scan = _scan,
.Processor = Me,
.Handled = False}
_mainContext.Send(AddressOf RaiseCapturedInProcessorEvent, cea) 'EXCEPTION HERE
End Sub
'executed in main thread
Private Sub RaiseCapturedInProcessorEvent(e As Object)
RaiseEvent CapturedInProcessor(Me, DirectCast(e, CapturedEventArgs))
End Sub
End Class
请问您知道为什么这些类型在运行时突然不兼容了吗?在我没有对继承的类型进行任何更改之前,代码就可以工作了。
我添加的东西是这种类型的事件的自定义事件中继。据我了解,应该不相关。
完整的异常文本:
System.InvalidCastException was unhandled
Message=Unable to cast object of type 'System.EventHandler`1[myProject.clsScannerProcessor+CapturedEventArgs]' to type 'System.EventHandler'.
Source=System.Windows.Forms
StackTrace:
at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)
at System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)
at System.Windows.Forms.WindowsFormsSynchronizationContext.Send(SendOrPostCallback d, Object state)
at vpsCRMsql.clsScannerProcessor.EvaluateScan() in ...
at vpsCRMsql.clsScannerProcessor.EvaluateKeystroke(stQueuedEvent keyEvent) in ...
at vpsCRMsql.clsScannerProcessor.WatchQueue() in ...
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
整体模型:
多个设备处理器(在不同的线程中运行)引发它们自己的事件,这些事件会通过事件中继引发一个公共事件。
事件中继(在 clsScannerManager 类中管理上述 clsScannerProcessor 的一个或多个实例)是这样的:
Public Class clsScannerManager
Public Custom Event Captured As EventHandler(Of clsScannerProcessor.CapturedEventArgs)
AddHandler(ByVal value As EventHandler(Of clsScannerProcessor.CapturedEventArgs))
_eventReceivers.Add(value)
End AddHandler
RemoveHandler(value As EventHandler(Of clsScannerProcessor.CapturedEventArgs))
_eventReceivers.Remove(value)
End RemoveHandler
RaiseEvent(sender As Object, e As clsScannerProcessor.CapturedEventArgs)
For Each handler As EventHandler In _eventReceivers
'some more complex work in here
Next
End RaiseEvent
End Event
Sub AddEventToProcessor(processor As clsScannerProcessor)
AddHandler processor.CapturedInProcessor, AddressOf RaiseCapturedEvent
End Sub
Sub RaiseCapturedEvent(sender As Object, e As clsScannerProcessor.CapturedEventArgs)
RaiseEvent Captured(sender, e)
End Sub
【问题讨论】:
-
Captured事件的定义在哪里?在我看来,这才是关键。 -
@roryap - 我还添加了一些其他可能很重要的东西(对不起,因为添加了很长的问题)
标签: .net vb.net events exception casting