天天看点

一个.Net的对象引用而引发的故事(记帮助用户现场解决)

作者:老唐谈物联

用户购买了我们的HY-2005C型超低功耗终端,应用场景是:4.2V锂电池给终端供电,终端升压(5V,9V,12V,24V)给流量计通信模块供电,485采集现场2台流量计数据,按每15分钟采集一次,每30分钟上传一次的频率,4G全网通工作模式,接收平台在我们提供的“应用服务器工具”源码上自行根据现场要求修改。

前期用户担心我们的产品不能达到其要求,先购买了一台用于测试,经过近一个月的测试,表明我们的产品在功耗、上传数据准确性方面,均完全满足要求,就实际进入批量采购,并到现场安装。

就在两天前,用户给我们打电话,说的是安装到现场的10多台设备,会偶尔缺少一台流量计的数据,而且这个不是某一台,是都可能出现,而且是随机性的,原因根据找不到,希望我们能帮忙分析一下,因为我们设备已经批量大规模应用,固件最近也没有做大的升级改动,所以第一反应应该不是设备的原因,因为我们的HY-2005C型终端采用的是存储->发送->确认,这么个流程,如果终端没有收到服务器的确认回复,那么这条数据会一直发送,所以推测问题应该在接收端。

由于接收端是基于我们公司提供的框架服务修改而来,用户说只是将接收的数据按照需要进行了解析入库操作,经过沟通,其采用的是我们提供的一个队列完成的,那么这里应该不是导致数据丢失的根本原因,经过讨论、分析,没有确定问题的原因,让其看原始TCP报文,根据LOG得出,我们终端是按照设定的频率和流量计上传的,所以100%排除设备原因,现在分析服务端,经过一段时间的讨论,没有得到结果,最后让用户发源码工程给到我们分析。

在收到源码后,发现用户在编程时,因变量的申请位置原因,导致存入队列的数据会被覆盖,具体代码如下:

一个.Net的对象引用而引发的故事(记帮助用户现场解决)

图1:用户将原始数据添加至队列

一个.Net的对象引用而引发的故事(记帮助用户现场解决)

图2:用户在另一个线程取数据并解析(问题就在这里)

细心的朋友就会发现,当只有一台设备时,这里不会有任何问题,但当多台设备时同时来数据时,第二次取的数据会将 saveingCustomHisData 这个对象的值给改变,由于在 .Net中,class声明的变量都是引用类型,所以这里会将前面的值改变,从而引发随机性数据丢失。

将这里声明的位置改到循环内,即可解决:

一个.Net的对象引用而引发的故事(记帮助用户现场解决)

图3:正确代码

至此,问题得以全面解决!

继续阅读