怪问题,求高手帮解决!!多线程中丢数据的问题
【背景介绍】:本人原来开发了一套多通道数据采集分析系统,分析软件开发环境是VS2010,.Net4.0,使用C#语言编写,配合NI measurement studio2010做图形显示,另外还用了DXPerience10的控件。
多通道采集器通过UDP协议与软件进行数据通讯,软件和采集器有一套完善的通讯协议,通讯过程是这样的,软件发送数据请求包,采集器将所有24通道数据发送给软件(24包)。为保证数据完整性,软件存储策略是收到全部数据后才同意存储,否则丢弃数据,等到下一帧数据。
该软件也开发完成较长时间,软件在【正常笔记本】上运行正常,win7 32位 64位 xp下都没问题。
【遇到的问题】本次想继续升级采集器,在采集器内部集成了一个【工控机模块】,安装了64位Win7,和正常电脑用起来没什么区别,用的是Atom CPU,软件直接在里面运行,可以脱离笔记本采集存储数据。
但是在原有软件和通讯协议未改动的情况下,发现软件在新采集器运行是实时数据显示卡顿,经常三四秒才更新数据(正常通讯是每秒请求一次数据,相应界实时数据显示也是每秒更新),起初怀疑工控机的CPU图形处理能力较差,导致界面不更新,但通过更深入的排查,发现是多线程丢包了。
具体判据如下:
(1)用抓包软件查看网络收发情况,发现通讯流畅不存在网络丢包的情况。
(2)在软件中添加相应代码监测实时数据情况发现,问题是由于负责接收数据的线程丢失数据,导致未收到完整24通道数据,软件存储策略将这一帧的数据丢弃所致。丢失数据的情况比较随机,正常共24包数据,每次丢数据时收到数据从十几包到23包不等。
(3)将线程中等待数据的时间延长,依然无法等到数据,确实是没了,不是迟了。。。
【目前所做的努力】
除上面所说监测代码运行情况抓包等工作外,本想将开发环境包括.net环境升级到更高版本,无奈配合使用NI mesurement Studio新版本的资源比较难找,暂时还没升级。
另外,原软件是在32位环境下开发的,编译成64位后也没啥改观。
【相关代码】
(1)主线程中等待数据代码
while (true)
{
try
{
allData=new byte[ChannelCount][];
receivedCount = 0;
//请求数据
Send(reqBuffer);
CanReceive = true;//开始接收
int waitTime = 0;
bool bOutTime = false;
Thread.Sleep(6);
while (receivedCount <ChannelCount) 收到数据不够24通道就不处理
{
Thread.Sleep(40);
waitTime++;
Debug.WriteLine("等待中" + DateTime.Now.ToString() + "-" + DateTime.Now.Millisecond.ToString() + "waittime" + waitTime);
if (waitTime > 10)
{
bOutTime = true;
break;
}
}
(2)子线程中处理数据部分代码,子线程是在主线程中开启的
public static void ReceiveThreadRun()
{
byte[] receivebytes;
while (true)
{
try
{
if (!CanReceive)
Thread.Sleep(2);
receivebytes = Receive();
while (receivedCount >= allData.Length && CanReceive)
Thread.Sleep(2);
try
{
allData[receivedCount] = receivebytes;
}
catch (Exception ex)
{
}
bool rs = 处理协议数据(receivebytes);
if(rs)
receivedCount++;
(3)子线程(2)中接收数据代码如下
private static byte[] Receive()
{
byte[] re;
MainForm.MaiInstance.网络状态 = Status.Running;
re=udpClient.Receive(ref localEndPoint);//接收数据代码
MainForm.MaiInstance.网络状态 = Status.DarkRunning;
return re;
}
对代码运行情况的监测最深就带这里,丢数据时监测这里运行情况就收不到数据了
目前就是以上的情况,望各位大神不吝赐教,先谢过了