Honeywell POS4NET两款扫描仪触发同一事件,如何区分设备?
解决Honeywell POS4NET多扫描仪事件sender混淆的问题
兄弟,我太懂你这个痛点了!同一驱动下的两款扫描仪,事件触发时sender总是指向最后创建的设备,根本分不清是谁扫的。其实核心原因就是两款设备共享了同一个ServiceObject实例(HHP.PointOfService.ServiceObjects.Scanner.HandHeldScanner),导致之前绑定的事件被后续的设备实例覆盖了。下面给你几个亲测有效的解决方案:
方案1:用Tag属性给每个设备打个“标签”
在初始化每个扫描仪的时候,把它的设备名称(或者你能识别的唯一标识)存到Tag属性里,这样事件触发时直接读Tag就能区分:
foreach (string device in listOfScanners) { var scanningDevice = posExp.CreateInstance(device) as Microsoft.PointOfService.Scanner; if (scanningDevice != null) { // 给当前设备打上标签,存下设备名 scanningDevice.Tag = device; scanningDevice.Claim(1000); scanningDevice.DeviceEnabled = true; scanningDevice.DataEvent += ScanningDevice_DataEvent; scanningDevice.DecodeData = true; scanningDevice.DataEventEnabled = true; scanningDevice.ErrorEvent += ScanningDevice_ErrorEvent; } }
然后在事件处理里直接拿Tag判断:
void ScanningDevice_DataEvent(object sender, DataEventArgs e) { Scanner scanner = (Scanner)sender; string deviceName = scanner.Tag as string; if (deviceName == "Voy1202g") { // 这是Voyager 1202g扫的,走对应的业务逻辑 } else if (deviceName == "Orbit7190g") { // 这是Orbit 7190g的扫描数据,处理它 } // 剩下的业务代码... }
方案2:给每个设备绑定专属的事件逻辑
别共用一个事件处理程序了,直接给每个扫描仪单独写事件逻辑,用闭包捕获当前的设备实例,这样就不会被后续的循环覆盖:
foreach (string device in listOfScanners) { var scanningDevice = posExp.CreateInstance(device) as Microsoft.PointOfService.Scanner; if (scanningDevice != null) { scanningDevice.Claim(1000); scanningDevice.DeviceEnabled = true; scanningDevice.DecodeData = true; scanningDevice.DataEventEnabled = true; // 给当前设备绑定专属的事件处理,闭包会捕获当前的scanningDevice scanningDevice.DataEvent += (s, eArgs) => { Console.WriteLine($"收到{device}的扫描数据:{scanningDevice.ScanDataLabel}"); // 这里直接处理当前设备的逻辑就行,绝对不会搞混 }; scanningDevice.ErrorEvent += ScanningDevice_ErrorEvent; } }
这个方法我之前处理类似问题时用过,效果特别好,完全不用担心sender混淆的问题。
方案3:读取设备的唯一标识属性
如果上面两种方案都不行,你可以试试读取扫描仪本身的唯一属性,比如DeviceName或者通过Properties集合拿硬件相关的标识:
void ScanningDevice_DataEvent(object sender, DataEventArgs e) { Scanner scanner = (Scanner)sender; // 直接拿设备名称判断 string deviceName = scanner.DeviceName; if (deviceName.Contains("1202g")) { // 处理Voyager 1202g的逻辑 } else if (deviceName.Contains("7190g")) { // 处理Orbit 7190g的逻辑 } }
额外提醒
你说改事件绑定顺序,识别到的设备也会变,这就坐实了驱动实例被覆盖的问题。优先用方案2的闭包方式,从根源上避免实例混淆;如果必须共用事件处理,方案1的Tag属性是最稳妥的。
内容的提问来源于stack exchange,提问作者Hermann Schachner
相关产品推荐
相关产品推荐

