如何把一个读取串口操作的自定义控件放入线程中? 由于读取串口操作是在控件中执行,因此一旦运行读取操作,主线程就会“卡死”,请问如何把一个读取串口操作的自定义控件放入线程中? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 delegate void ProcessDelegate(string sPortData); //代理(同步显示串口数据) private ProcessDelegate process; /// <summary> /// 设置controlLED显示数据 /// </summary> /// <param name="sNum">要显示的数字</param> private void setLED(string sPortData) { this.iLEDnum = int.Parse(sTrData); } /// <summary> /// 串口数据激活事件 ReceivedBytesThreshold = 12 每12字节激活一次 /// </summary> private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) { try { InputData = this.serialPort1.ReadTo("="); if (InputData != String.Empty && InputData.Length == 8) { process(InputData); } } catch { } }我使用的是代理!!但是好像没有作用!! process = new ProcessDelegate(setLED); private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) { Thread tReceive=new Thread(new ThreadStart(ReceiveData)); tReceive.Start(); } private void ReceiveData() { //这里面放读操作代码 try { InputData = this.serialPort1.ReadTo("="); if (InputData != String.Empty && InputData.Length == 8) { process(InputData); } } catch { } } DataReceived 是每12个字节自动执行一次!!会不会产生线程太多了? 如何最优化执行呢? 先谢谢 dancingbit 的帮助! 我对于线程方面的操作不太了解!!我的思路是这样的!! DataReceived 是每12个字节自动执行一次! 在自动触发时,开启线程读取数值,然后启动委托更新界面控件数值,更新完毕,线程挂起运行!那么如何做呢?我测试使用在load时启动线程: private void LED_Load(object sender, EventArgs e) { tReceive = new Thread(new ThreadStart(ReceiveData)); tReceive.Start(); }然后在 private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) { if(线程运行状态) { tReceive.Start(); } else { tReceive.Suspend(); } }但是好像不行!!还有线程运行状态如何判断?IsAlive吗? IsAvlive只是判断该线程是否存活,判断状态需使用ThreadState挂起后恢复也不是使用Start,而是使用Resume tReceive.ThreadState == ThreadState.Running ?? if(tReceive.ThreadState==ThreadState.Suspended) tReceive.Resume();至于挂起的时机,应在读完当前的数据之后还是那个意见,要么就别挂起了,根据某个标志变量判断当前有没有数据可读,没有数据就不断地Thread.Sleep如下形式:while(true){ if(终止变量为真) break; if(有数据可读) {//读数据 } else Thread.Sleep(300);} 9600 波特的!! 一前在 1200 低下测试没有卡死 可能就是数据处理占用了大量的CPU! 要不您还是先用一下Windows中的超级终端测试一下吧. 注意主要的配置1. data bit 2. port3. parity4. stop bits5. max speed6. flow 这些都是串口通讯的参数,如果配制有问题,会卡死的。 kindyaloner 这些设置都是按照设备说明书配置的!! www.codeproject.com上有专门介绍线程的例子,感觉你可以用线程同步去做,没必要把线程挂起, 没必要把它放到线程里,是在vs2005下,线程不允许访问主界面代码。用代理就可以了 if (m_list.InvokeRequired) { m_list.Invoke(new EventHandler(delegate { m_list.Text = str + "\r\n" + m_list.Text; } )); } else { m_list.Text = str + "\r\n" + m_list.Text; }m_list是你要显示串口来的数据。 jiayp004 谢谢你的回复!!不过我的控件是数据显示在控件内的LED中!!不用单独在主界面刷新显示!!为了防止串口数据显示控件读取串口数据时引起主界面假死,所以想要实现把串口数据显示控件放入线程运行! 串口接收数据最好Sleep下,减轻CPU负担 使用Sleep容易造成主线程假死!! 怎样用正则表达式把代码中展示出来的信息提取出来 IBatisNet偶尔会出现这个错:Could not load type from string value 'Domain.Adv' 登录请求问题 按回车让下一控件获得焦点 如何使最小化窗体的窗体在还原时执行messagebox.show("已还原")? WinFrom多窗体间如何实现for循环切换,在线等啊,急? com组件的问题 面试问题 C#如何将字符串转成类类型,并将一个存在的对象强制转成转换过来的类类型 怎样在数据绑定到DATAGRID之前,先判断其中一个字段是否为空? 用Graphic类绘图的疑问。 Type.GetType
private ProcessDelegate process; /// <summary>
/// 设置controlLED显示数据
/// </summary>
/// <param name="sNum">要显示的数字</param>
private void setLED(string sPortData)
{
this.iLEDnum = int.Parse(sTrData);
}
/// <summary>
/// 串口数据激活事件 ReceivedBytesThreshold = 12 每12字节激活一次
/// </summary>
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
InputData = this.serialPort1.ReadTo("=");
if (InputData != String.Empty && InputData.Length == 8)
{
process(InputData);
}
}
catch
{ }
}我使用的是代理!!但是好像没有作用!!
{
Thread tReceive=new Thread(new ThreadStart(ReceiveData));
tReceive.Start();
} private void ReceiveData()
{
//这里面放读操作代码
try
{
InputData = this.serialPort1.ReadTo("=");
if (InputData != String.Empty && InputData.Length == 8)
{
process(InputData);
}
}
catch
{ }
}
private void LED_Load(object sender, EventArgs e)
{
tReceive = new Thread(new ThreadStart(ReceiveData));
tReceive.Start();
}然后在
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if(线程运行状态)
{
tReceive.Start();
}
else
{
tReceive.Suspend();
}
}但是好像不行!!还有线程运行状态如何判断?IsAlive吗?
挂起后恢复也不是使用Start,而是使用Resume
tReceive.Resume();至于挂起的时机,应在读完当前的数据之后还是那个意见,要么就别挂起了,根据某个标志变量判断当前有没有数据可读,没有数据就不断地Thread.Sleep如下形式:while(true)
{
if(终止变量为真)
break;
if(有数据可读)
{//读数据
}
else
Thread.Sleep(300);
}
2. port
3. parity
4. stop bits
5. max speed
6. flow 这些都是串口通讯的参数,如果配制有问题,会卡死的。
上有专门介绍线程的例子,
感觉你可以用线程同步去做,没必要把线程挂起,
if (m_list.InvokeRequired)
{
m_list.Invoke(new EventHandler(delegate
{
m_list.Text = str + "\r\n" + m_list.Text;
}
));
}
else
{
m_list.Text = str + "\r\n" + m_list.Text;
}
m_list是你要显示串口来的数据。