c#的datagridview硬件采样速度过慢

qq_39258463 2019-01-09 07:23:32
正在进行把delphi代码改成c#代码的操作,光纤陀螺以300hz的频率提供角速度,测速码盘提供线速度,单片机提供时间,然后通过WiFi模块与电脑相连,delphi和c#都是通过串口控件来进行数据的接收,在delphi的drawgrid控件里,每秒可以刷新约300行数据,但是在c#的datagridview控件里,每秒只能刷新约150行数据,而且delphi中显示的采样时间间隔是26,52均匀排列,但是c#的时间间隔基本上没有26,很多都是52,中间夹杂着许多100多,200多的时间间隔,这应该是采样速度跟不上,我把数据后面加上当前的时间,然后存进datagridview和textbox中,每秒钟收到的数据个数差不多的,所以基本可以排除数据写入datagridview速度过慢的问题,请问各位大佬出现这种情况的原因是什么呢?该怎么解决这个问题?是不是c#的serialport控件最大只能以150hz的频率接收数据呢?
...全文
1244 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
ilikeff8 2019-01-16
  • 打赏
  • 举报
回复
是的,上面开线程了,控制ui部分要invoke
hez2010 2019-01-16
  • 打赏
  • 举报
回复
引用 19 楼 qq_39258463 的回复:
引用 18 楼 hez2010 的回复:
不要让绘制UI阻塞住你的事件处理函数。正确的做法是收到数据后将相应的东西交由UI线程去做,而不是阻塞在工作线程
哦哦,那具体应该怎么操作呢?我程序中已经有form1_load事件了,请问多线程编程中是要用到main函数吗,这两个一起使用话会报错啊,说程序定义了多个入口点,这个要怎么解决呢

不好意思,因为我没有用过WinForm不知道那里的代码具体应该怎么写。如果是WPF的话可以使用 Dispatcher.BeginInvoke(new Action(() => { ...... }));
qq_39258463 2019-01-14
  • 打赏
  • 举报
回复
引用 18 楼 hez2010 的回复:
不要让绘制UI阻塞住你的事件处理函数。正确的做法是收到数据后将相应的东西交由UI线程去做,而不是阻塞在工作线程
哦哦,那具体应该怎么操作呢?我程序中已经有form1_load事件了,请问多线程编程中是要用到main函数吗,这两个一起使用话会报错啊,说程序定义了多个入口点,这个要怎么解决呢
hez2010 2019-01-13
  • 打赏
  • 举报
回复
不要让绘制UI阻塞住你的事件处理函数。正确的做法是收到数据后将相应的东西交由UI线程去做,而不是阻塞在工作线程
qq_39258463 2019-01-13
  • 打赏
  • 举报
回复
引用 14 楼 ilikeff8 的回复:
using System.Collections.Concurrent;

不行啊,加了这些代码反而更卡了,时间间隔变成了几万,几十万,有时候甚至停住不动了,请问这些代码就是使用了多线程吗
ilikeff8 2019-01-11
  • 打赏
  • 举报
回复

BlockingCollection<byte[]> ProcessInputQueue = new BlockingCollection<byte[]>();
static object serialPortLock = new object();
bool isAllowInput = false;

void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (isAllowInput)
{
lock (serialPortLock)
{
int byteCount = serialPort.BytesToRead;
byte[] receiveBytes = new byte[byteCount];

serialPort.Read(receiveBytes, 0, byteCount);
ProcessInputQueue.Add(receiveBytes);
}
}
else
{
serialPort.DiscardInBuffer();
}
}

void StartProcessInputLoop()
{
ThreadPool.QueueUserWorkItem(obj =>
{
while (true)
{
foreach (byte[] bytes in ProcessInputQueue.GetConsumingEnumerable())
{
string info = Encoding.UTF8.GetString(bytes);
}
}
});
}
qq_39258463 2019-01-11
  • 打赏
  • 举报
回复
引用 6 楼 圣殿骑士2018 的回复:
没用好多线程编程,采集所在的线程和datagridview所在的UI线程需要异步。
哦哦,我程序中已经有form1_load了,请问多线程编程中是要用到main函数吗,这两种一起使用话会报错啊,说程序定义了多个入口点,这个要怎么解决呢
qq_39258463 2019-01-11
  • 打赏
  • 举报
回复
引用 9 楼 xuzuning 的回复:
看看你的代码

private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
int i;
double temp0, temp1, temp2, temp3, temp4, temp5;

for (i = 0; i < serialPort1.BytesToRead; i++)
{
reC = Convert.ToByte(serialPort1.ReadByte());
if ((reC == 221) && (rflag == 0))
{
rflag = 1;
rcount = 1;
}
if ((rflag == 1) && (rcount < 9))
{
reInt[rcount - 1] = reC;
rcount = rcount + 1;
}
if (rcount == 9)
{
rflag = 0;
rcount = 0;
// 计算角速度
TLAngle = reInt[1] + reInt[3] * 256 + reInt[2] * 256 * 256;
if ((reInt[2] & 128) == 128)
{
long x = 0xFF000000;
int y = (int)x;
TLAngle = TLAngle | y;
TTLFlag = reInt[7] >> 7 & 1;//计算脉冲
LocaFlag = reInt[7] >> 6 & 1;//计算位置
if (LocaFlag == 1)
LocaCount = LocaCount + 1;
if (LocaCount > 1)
{
if (Convert.ToSingle(dataGridView1.Rows[DrawR - 1].Cells[4].Value) < 9)
{
LocaFlag = 0;
LocaCount = LocaCount - 1;
}
}
if ((LocaCount == 1) && (locSt == 0) && (LocaFlag == 1))
{
if (XX > 1)
{
UpCount_old = all_Num;
Theta_st = Math.Atan(Convert.ToSingle(dataGridView1.Rows[DrawR - 2].Cells[5].Value) / Convert.ToSingle(dataGridView1.Rows[DrawR - 2].Cells[4].Value));
DrawGrid_st = DrawR - 1;
dataGridView1.Rows[DrawR - 1].Cells[4].Value = "0"; // XX
dataGridView1.Rows[DrawR - 1].Cells[5].Value = "0"; // YY
XX = 0; // 避免画出预行进距离
YY = 0;
timer1.Enabled = true;
pre_route_flag = 1;
locSt = 1;
}
else
{
LocaFlag = 0; // 避免预跑过程中,出现其它位置传感器
LocaCount = LocaCount - 1;
}
}
if ((LocaCount > 1) && ((all_Num - UpCount_old) > 1000) && (locSt == 1))
{
timer1.Enabled = false;
DrawGrid_ed = DrawR - 1;
dataGridView1.Rows[DrawR - 1].Cells[6].Value = "第二个位置传感器";
Theta_ed = Math.Atan(Convert.ToSingle(dataGridView1.Rows[DrawR - 1].Cells[5].Value) / Convert.ToSingle(dataGridView1.Rows[DrawR - 1].Cells[4].Value));
locSt = 2;
button3_Click(sender, e);//此处有争议,原代码是button3_click(form1)
//break;
}
reInt[7] = reInt[7] & 0x3F;
TLTime_orig = reInt[4] + reInt[5] * 256 + reInt[6] * 256 * 256 + reInt[7] * 256 * 256 * 256;
all_Num = all_Num + 1;
Inst_TLAngle = TLAngle / Convert.ToSingle(comboBox2.Text);
if ((TTLFlag == 1) && (UpCount == 0))
{
dataGridView1.Rows[2].Cells[0].Value = Convert.ToString(Inst_TLAngle); //陀螺值
UpCount = UpCount + 1;
if ((TLTime_orig - TLTime_orig_old) > 200)
TLTime_orig = TLTime_orig_old + 27;

TTL_Time_st = TLTime_orig;

}
if ((TTLFlag == 0) && (UpCount > 0))
{
avg_TLAngle = avg_TLAngle + Inst_TLAngle;
UpCount = UpCount + 1;
}
if ((TTLFlag == 1) && (UpCount > 0))
{
if ((TLTime_orig - TLTime_orig_old) > 200)
TLTime_orig = TLTime_orig_old + 27;

TTL_Time_ed = TLTime_orig;

if ((TTL_Time_ed > TTL_Time_st))
{
DataGridViewRow newrow = dataGridView1.Rows[this.dataGridView1.Rows.Add()];
newrow.Cells[0].Value = dataGridView1.Rows.Count;
// dataGridView1.Rows[DrawR].Cells[0].Value = (DrawR + 1).ToString(); // 序号

avg_TLAngle = (avg_TLAngle + Inst_TLAngle) / (UpCount);
dataGridView1.Rows[DrawR].Cells[2].Value = Convert.ToString(avg_TLAngle); //陀螺值

Timedis = TTL_Time_ed - TTL_Time_st;
dataGridView1.Rows[DrawR].Cells[1].Value = Convert.ToString(Timedis);// 时间间隔

temp3 = Convert.ToSingle(dataGridView1.Rows[DrawR - 1].Cells[3].Value); //角度
temp1 = Convert.ToSingle(dataGridView1.Rows[DrawR - 1].Cells[2].Value); // 陀螺值
temp2 = Convert.ToSingle(dataGridView1.Rows[DrawR - 1].Cells[1.Value); // 时间间隔
temp4 = Convert.ToSingle(dataGridView1.Rows[4].Cells[DrawR - 1].Value); // XX
temp5 = Convert.ToSingle(dataGridView1.Rows[5].Cells[DrawR - 1].Value); // YY

temp0 = temp3 + (temp1 - earth_eagle) * temp2 / 7.8 / 1000;
dataGridView1.Rows[DrawR].Cells[3].Value = Convert.ToString(temp0); // 角度

XX = temp4 + car_plus * Math.Cos(temp0 * 3.1415926 / 180 - Theta_st);
dataGridView1.Rows[DrawR].Cells[4].Value = Convert.ToString(XX); // XX

YY = temp5 + car_plus * Math.Sin(temp0 * 3.1415926 / 180 - Theta_st);
dataGridView1.Rows[DrawR].Cells[5].Value = Convert.ToString(YY); ; // YY

TTL_Time_st = TTL_Time_ed;
avg_TLAngle = 0;
DrawR = DrawR + 1;
dataGridView1.RowCount = DrawR;
UpCount = 1;
ilikeff8 2019-01-11
  • 打赏
  • 举报
回复
using System.Collections.Concurrent;
qq_39258463 2019-01-11
  • 打赏
  • 举报
回复
引用 3 楼 ilikeff8 的回复:
或者是你接收数据的代码要优化


未能找到类型或命名空间名“BlockingCollection<>”(是否缺少 using 指令或程序集引用?),请问出现这种错误要怎么解决呢?是要引用哪个程序集呢
圣殿骑士18 2019-01-10
  • 打赏
  • 举报
回复
没用好多线程编程,采集所在的线程和datagridview所在的UI线程需要异步。
xuzuning 2019-01-10
  • 打赏
  • 举报
回复
看看你的代码
qq_39258463 2019-01-10
  • 打赏
  • 举报
回复
引用 4 楼 stevenjin 的回复:
在文本文件接收看下效果
效果和datagridview中的差不多,都是每秒钟刷新70个左右的数据
qq_39258463 2019-01-10
  • 打赏
  • 举报
回复
引用 2 楼 ilikeff8 的回复:
serialport 波特率设置正确了不
和delphi中的是一样的,都是38400
threenewbee 2019-01-09
  • 打赏
  • 举报
回复
放在工作线程里,datagridview和你的采集速度没关系
stevenjin 2019-01-09
  • 打赏
  • 举报
回复
在文本文件接收看下效果
ilikeff8 2019-01-09
  • 打赏
  • 举报
回复
或者是你接收数据的代码要优化
ilikeff8 2019-01-09
  • 打赏
  • 举报
回复
serialport 波特率设置正确了不
xuzuning 2019-01-09
  • 打赏
  • 举报
回复
串口参数?

110,537

社区成员

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

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

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