事件管理表示用于 Microsoft Point of Service for .NET (POS for .NET) 的编程应用程序的关键方面之一。 POS for .NET 系统中的所有输入都是事件驱动的,POS for .NET 体系结构的每个段都使用事件与其他应用程序和服务对象进行通信。
事件驱动的处理模型
当附加的 POS 设备接收数据输入时,事件驱动的输入就开始了。 如果该设备已启用(DeviceEnabled 属性设置为 true),接收的数据将作为 DataEvent 事件排队并发送到应用程序。 事件由内部服务线程以先入先出的方式传递。 在引发此事件之前,服务对象可以使用 PreFireEvent 方法,在发出该事件之前更新属性。
接收到事件数据后,如果 AutoDisable 属性设置为 true,设备将自动自行禁用(将 DeviceEnabled 属性设置为 false)。 禁用后,设备无法对新输入进行排队,如果可能,物理设备将被禁用。
当应用程序准备好接收来自设备的输入时,它会将 DataEventEnabled 属性设置为 true。 然后,应用程序开始接收已排队的 DataEvent 事件,即使这些 DataEvent 事件在 DataEventEnabled 属性设置为 true 之前就已经排队了。
通过将 DataEventEnabled 属性或 FreezeEvents 属性设置为 false,可以禁用其他数据事件。 这会导致后来的输入数据在应用程序处理当前输入和关联的属性时排队。 当应用程序准备好获取更多数据时,它可以通过将 DataEventEnabled 属性设置为 true 来重新启用事件。
事件驱动的输入和设备共享
如果输入设备是专用设备,应用程序必须先声明并启用设备,然后才能使用它读取输入。
如果设备是可共享的,必须先打开一个或多个应用程序并启用该设备,然后才能使用它读取输入。 在服务对象使用 DataEvent 向设备发送数据之前,应用程序必须调用 Claim 方法以请求对设备的独占访问。 如果接收到事件驱动的输入,但设备仍未进行声明,输入会进行缓冲,直到应用程序声明设备并且 DataEventEnabled 属性设置为 true。 此行为可以促进在多个应用程序之间有序地共享设备,从而有效地在它们之间传递输入焦点。
事件驱动的输入和错误处理
如果在接收事件驱动的输入时遇到错误,设备就会进入错误状态。 然后,它对 ErrorEvent 事件(包含 InputData 或 Input ErrorEvent 位点)进行排队。 在 DataEventEnabled 属性设置为 true 之前不会传递这些事件,以确保有序地进行应用程序排序。 每个 ErrorEvent 指示具体是两个可能的错误位点中的哪一个:
- InputData - 如果在一个或多个 DataEvent 事件排队时发生错误,则使用它。 ErrorEvent 跳转到事件队列的队列头以立即处理,以便应用程序可以通过清除输入或通知用户有错误来立即响应。 然后完成缓冲输入的处理。
- Input - 如果发生错误且没有可用数据,则使用它。 如果在发生错误时输入数据已排队,具有 InputData 位点的 ErrorEvent 会排入队列并先行传递,然后引发并处理队列中剩余的 DataEvents。 最后,发送具有 Input 值的 ErrorEvent,指示队列为空,没有可用的数据。 值得注意的是,如果传递了具有 InputData 值的 ErrorEvent,并且应用程序事件处理程序响应了 Clear 值,则不会传递此 InputDataErrorEvent。 通常,会在事件队列的末尾进入此错误状态。
发生以下情况之一时,设备可能会退出“错误”状态:
- 应用程序从 InputErrorEvent 返回。 应用程序从 InputDataErrorEvent 返回,其中 ErrorResponse 属性为 Clear 值。
- 应用程序调用 ClearInput 方法。
对于某些设备,应用程序必须调用某个方法才能开始事件驱动的输入。 服务对象接收输入后,通常不会收到其他输入,直到再次调用该方法。 使用这种事件驱动的输入变体(也称为异步输入)的设备示例包括磁墨字符识别 (MICR) 设备和签名捕获设备。 可以读取 DataCount 属性以获取队列中的 DataEvent 事件数。
可以通过调用 ClearInput 方法来删除队列中的所有输入。 对于专用设备,可以在 Claim 后调用 ClearInput,或者,对于可共享设备,可以调用 Open。
常规事件驱动的输入模型不会阻止定义包含可直接返回输入数据的方法或属性的设备类。 这种事件驱动的输入变体(也称为同步输入)的一个示例是键锁设备。
事件类型
POS for .NET 将统一服务点 (UnifiedPOS) 事件作为具有多播委托的标准 .NET 事件来实现。 这些事件通知应用程序有关设备的各种活动或更改,例如添加或删除设备时。 下表列出了事件类型。
事件 | 说明 |
---|---|
DataEvent | 服务对象引发的事件,用于通知应用程序输入数据可用。 |
ErrorEvent | 服务对象引发的事件,用于通知应用程序发生了设备错误,并且应用程序必须做出适当的响应来处理错误情况。 |
StatusUpdateEvent | 服务对象引发的事件,用于提醒应用程序设备状态有所更改。 |
OutputCompleteEvent | 服务对象引发的事件,用于通知应用程序排队的输出请求已成功完成。 |
DirectIOEvent | 服务对象引发的事件,用于将信息直接传达给应用程序。 |
服务对象必须将这些事件堆叠在内部创建的托管队列上。 事件以先入先出的方式传递,并由内部服务线程传递。
以下条件会导致事件传递延迟,直到该条件得到更正:
- 应用程序已将 FreezeEvents 属性设置为 true。 FreezeEvents 属性允许将事件排队,但会阻止其传递,直到 FreezeEvents 设置为 false。
- 事件是 DataEvent 或输入 ErrorEvent,但属性 DataEventEnabled 为 false。
事件队列管理规则如下:
- 设备只能在启用设备时将新事件排队。
- 设备会传送排队事件,直到应用程序调用 Close 方法,或者对于专用设备,调用 Release 方法。 调用这些方法时,将删除队列中的任何剩余事件。
- ClearInput 方法清除了 DataEvents 和输入 DeviceErrorEvents(ErrorLocus = Input 或 InputData)。
- ClearOutput 方法清除了输出 DeviceErrorEvents (ErrorLocus = Output)。