You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 10:03:53