请教一个多线程方面的问题,窗体假死。

xiaowin88 2012-06-07 10:36:22
我在主线程中开启了两个线程,一个用于数据采集(用的数据采集卡) ,一个用于数据处理
程序刚启动都正常,按钮都可以
开始操作之后就出现假死代码在相面。程序有点多,麻烦大家啦,求指点一下,结构啊 啥的都可以。
这是开始代码:(collectThread 是采集线程;handleThread是数据处理线程)

public void btnStart_Click(object sender, EventArgs e)
{
//读取数据
DeviceLgcID = 0;
hDevice = PCI8620.PCI8620_CreateDevice(DeviceLgcID); // 创建设备对象
if (hDevice == (IntPtr)(-1))
{
printMessage("请检查设备是否安装正确!");
btnStart.Enabled = true;
return;
}
// 预置硬件参数
//ADPara.ADMode = PCI8620.PCI8620_ADMODE_SEQUENCE;
ADPara.FirstChannel = 0; // 首通道0
ADPara.LastChannel = 1; // 末通道1
ADPara.Frequency = 100000; // 采样频率(Hz)
ADPara.GroupInterval = 1; // 组间间隔(uS)
ADPara.Gains = PCI8620.PCI8620_GAINS_1MULT;
ADPara.InputRange = InputRange; // 模拟量输入量程范围
ADPara.TriggerMode = PCI8620.PCI8620_TRIGMODE_SOFT; // 触发模式为软件触发
ADPara.TriggerSource = PCI8620.PCI8620_TRIGSRC_ATR; // 选择外部ATR作为触发源
ADPara.TrigLevelVolt = 0;
ADPara.TriggerType = PCI8620.PCI8620_TRIGTYPE_EDGE; // 边沿触发
ADPara.TriggerDir = PCI8620.PCI8620_TRIGDIR_NEGATIVE; // 触发方向为负向
ADPara.ClockSource = PCI8620.PCI8620_CLOCKSRC_IN; // 内部时钟
ADPara.bClockOutput = PCI8620.PCI8620_CLOCKOUT_DISABLE; // 禁止本卡上的自带时钟向外输出
bRet = PCI8620.PCI8620_InitDeviceProAD(hDevice, ref ADPara) > 0; // 初始化硬件
if (!bRet)
{
printMessage("初始化设备失败!");
PCI8620.PCI8620_ReleaseDeviceProAD(hDevice);
PCI8620.PCI8620_ReleaseDevice(hDevice);
}
Int32 ChannelCount;
ChannelCount = ADPara.LastChannel - ADPara.FirstChannel + 1;
nReadSizeWords = 8192 - 8192 % (UInt32)ChannelCount; // 将数据长度字转换为双字
bRet = PCI8620.PCI8620_StartDeviceProAD(hDevice) > 0; // 启动设备
if (!bRet)
{
printMessage("启动设备失败!");
PCI8620.PCI8620_ReleaseDeviceProAD(hDevice);
PCI8620.PCI8620_ReleaseDevice(hDevice);

}
collectThread = new Thread(new ThreadStart(CollectData));
handleThread = new Thread(new ThreadStart(HandleData));
handleThread.Start();
collectThread.Start();
printMessage("开启数据接收卡!");
printMessage("开始接收数据!");
btnStart.Enabled= false;
btnStop.Enabled = true;
//读取数据
}

采集代码:

void CollectData()
{
int ReadIndex = 0;
int SegmentCount = 0;
while(true)
{
bRet = PCI8620.PCI8620_ReadDeviceProAD_Npt(hDevice, ref ADBuffer[ReadIndex, 0], nReadSizeWords, ref nRetSizeWords) > 0;//是用的一个dll里面的函数,ADBuffer[ReadIndex, 0]是我的缓冲区一个二维数组(全局定义UInt32[,] ADBuffer = new UInt32[32,8192]; 当ADBuffer[0, 0]相当于第一个缓冲区采集满数据)
SegmentCount++;
ReadIndex++;
if (SegmentCount==31)
{
SegmentCount = 0;
}
if (ReadIndex==31)
{
ReadIndex = 0;
}
nowSegmentCount = SegmentCount;
}
}

数据处理代码:

//处理数据
void HandleData()
{
Thread.Sleep(1000);
double xx = 0, yy = 0;
int flagCountI1 = int.Parse(sysFile.ReadString("SYSTEM", "INTERVALI1", "5"));
int flagCountI2 = int.Parse(sysFile.ReadString("SYSTEM", "INTERVALI2", "5"));
var closedLoopCie = sysFile.ReadString("SYSTEM", "ClosedloopCoefficient", "");
var clearedNum1 = sysFile.ReadString("SYSTEM", "averageClearedNum1", "");
var clearedNum2 = sysFile.ReadString("SYSTEM", "averageClearedNum2", "");
//配置采样点
var sampLingNum = sysFile.ReadString("SYSTEM", "SAMPLINGNUM", "");
while (true)
{
int handleSegmentCount = nowSegmentCount;//(nowSegmengtCount是全局变量,主要是获取采集里面的那个二维数组采集到那个缓冲区了)
for (int i = 0; i < handleSegmentCount; i++)
{
for (int j = 0; j < 8192; j++)
{
//if (i == 31)
//{
// i = 0;
//}
fVolt = (20000.00 / 8192) * (ADBuffer[i, j] & 0x1FFF) - 10000.00;
             ..................
            ............//这里主要是电压的一些转换和一些计算代码很多
}
       }
}

代码也多 求教各位了是不是winform方面那些东西我没设置还是啥的,分不多,只有100分,
...全文
123 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaowin88 2012-06-07
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

while循环中给cpu一点时间,加上 Thread.Sleep(xxx);试试
[/Quote]
谢谢 30分送上。原因是我那个刷新gdi绘图的方法问题,刷新量太大了。我另外开启了一个线程控制刷新频率
xiaowin88 2012-06-07
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

两个while (true)
的线程不停的做事,把CPU都占掉了,不信你看看你的CPU使用率。
你好歹在每次循环之后切换一下线程吧。
Sleep(1)
[/Quote]
谢谢 30分送上。原因是我那个刷新gdi绘图的方法问题,刷新量太大了。我另外开启了一个线程控制刷新频率
xiaowin88 2012-06-07
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]

引用 9 楼 的回复:
引用 8 楼 的回复:

看你的代码都是一些不可避免的操作,这样 cpu 使用率高也没办法,只能当作程序对硬件环境有要求


您看啊 数据处理线程代码里的这一段

C# code

int handleSegmentCount = nowSegmentCount;//(nowSegmengtCount是全局变量,主要是获取采集里面的那个二维数组采集到……
[/Quote]
这是一个 二维数组 xx[32][8192]我实时的把里面的数据循环出来 里面的计算倒还好 就是分双通道输出。然后先进先出的控制在5000个
__天涯寻梦 2012-06-07
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 的回复:]
引用 8 楼 的回复:

看你的代码都是一些不可避免的操作,这样 cpu 使用率高也没办法,只能当作程序对硬件环境有要求


您看啊 数据处理线程代码里的这一段

C# code

int handleSegmentCount = nowSegmentCount;//(nowSegmengtCount是全局变量,主要是获取采集里面的那个二维数组采集到那个缓冲区了)
……
[/Quote]
访问变量不会引起这个现象的,顶多是数据出错,这一段才是大头
for (int j = 0; j < 8192; j++)
{
//if (i == 31)
//{
// i = 0;
//}
//fVolt = (20000.00 / 8192) * (ADBuffer[i, j] & 0x1FFF) - 10000.00;
//    ..................
//   ............//这里主要是电压的一些转换和一些计算代码很多
}
xiaowin88 2012-06-07
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]

看你的代码都是一些不可避免的操作,这样 cpu 使用率高也没办法,只能当作程序对硬件环境有要求
[/Quote]

您看啊 数据处理线程代码里的这一段

int handleSegmentCount = nowSegmentCount;//(nowSegmengtCount是全局变量,主要是获取采集里面的那个二维数组采集到那个缓冲区了)
for (int i = 0; i < handleSegmentCount; i++)


里面那个nowSegmentCount是全局的 两个线程都在用 会不会导致这种原因的呢
__天涯寻梦 2012-06-07
  • 打赏
  • 举报
回复
看你的代码都是一些不可避免的操作,这样 cpu 使用率高也没办法,只能当作程序对硬件环境有要求
xiaowin88 2012-06-07
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

两个while (true)
的线程不停的做事,把CPU都占掉了,不信你看看你的CPU使用率。
你好歹在每次循环之后切换一下线程吧。
Sleep(1)
[/Quote]
这样CPU还是100% 不过比第一次好一点 会有时候是98%
xiaowin88 2012-06-07
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

简单点就两个 while 里最后一行都加上线程休息的代码
C# code
while (true)
{
Thread.Sleep(1000);
}
[/Quote]
这样CPU还是100% 不过比第一次好一点 会有时候是98%
xiaowin88 2012-06-07
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

while循环中给cpu一点时间,加上 Thread.Sleep(xxx);试试
[/Quote]
这样CPU还是100% 不过比第一次好一点 会有时候是98%
__天涯寻梦 2012-06-07
  • 打赏
  • 举报
回复
简单点就两个 while 里最后一行都加上线程休息的代码
while (true)
{
Thread.Sleep(1000);
}
bdmh 2012-06-07
  • 打赏
  • 举报
回复
while循环中给cpu一点时间,加上 Thread.Sleep(xxx);试试
xiaowin88 2012-06-07
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

两个while (true)
的线程不停的做事,把CPU都占掉了,不信你看看你的CPU使用率。
你好歹在每次循环之后切换一下线程吧。
Sleep(1)
[/Quote]
cpu是100%哦 切换下线程?如何弄哦 拜托您啦 我学自动化的 刚写这个代码 不是很了解哦
cheng2005 2012-06-07
  • 打赏
  • 举报
回复
两个while (true)
的线程不停的做事,把CPU都占掉了,不信你看看你的CPU使用率。
你好歹在每次循环之后切换一下线程吧。
Sleep(1)

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧