多线程发送,接收串口数据
平静大海 2011-08-26 09:58:14 目前多线程接收,解析数据处理好了,但用多线程发送数据时数据出了问题,一是有些指令没有数据返回,二是线程执行顺序是错了,我是用c#.NET 线程池处理的
小弟想实现这样的功能,用多线程发送数据,多线程接收数据,多线程解析数据,保证实时读取串口接收的数据。可下面贴出来的这些方法没有实现要的功能,琢磨了快一个星期了,希望各位大哥指教,能给好的指导思想,有串口多线程发送,接收的项目例子更好。
/// <summary>
/// 发送多条指令,用异步的方式接收数据
/// </summary>
/// <param name="vData">发送的数据和读取返回的数据)</param>
/// <param name="IsReturn">true 读取返回的数据 false 不返回数据)</param>
/// <returns></returns>
public bool SendData(string[] cmd, string tagData, bool fag)
{
DateTime a1 = DateTime.Now;
//for (int i = 0; i < 1000; i++)
//{
foreach (string s in cmd)
{
if (s == string.Empty || tagData == string.Empty)
return false;
if (!serialState)
this.InitPortCom();
tab = parms.PtlParms(s);
if (tab == null || tab.Rows.Count == 0)
return false;
DataRow frameData = tab.Select(string.Format("type='{0}' and name='{1}' ", "Output", "命令长度"))[0];
int frameLen = Convert.ToInt32(basefun.valtag(frameData["pms"].ToString(), "{命令长度}")) * 2 + 12;
byte[] buffData = analy.SetPtlData(tab, tagData);
serialPort.Write(buffData, 0, buffData.Length);
this.WaiteSendData(new SendTaskInfo(buffData, s));
this.WaiteReceiveData(new ReceiveTaskInfo(s, frameLen));
this.WaitAnalysisData(new ReceiveTaskInfo(s, frameLen));
}
return true;
}
/// <summary>
/// 开启线程循环发送数据
/// </summary>
private void WaiteSendData(object data)
{
if (!serialPort.IsOpen)
return;
SendTaskInfo state = data as SendTaskInfo;
System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(ThreadSend), state);
}
/// <summary>
/// 开启线程循环取帧
/// </summary>
private void WaiteReceiveData(object data)
{
if (!serialPort.IsOpen) return;
ReceiveTaskInfo state = data as ReceiveTaskInfo;
System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(ThreadReceive), state);
}
/// <summary>
/// 开启线程解析数据
/// </summary>
/// <param name="data"></param>
private void WaitAnalysisData(object data)
{
if (!serialPort.IsOpen) return;
ReceiveTaskInfo state = data as ReceiveTaskInfo;
System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(GetData), state);
}
/// <summary>
/// 开启一个线程发送数据
/// </summary>
/// <param name="state"></param>
private void ThreadSend(object state)
{
SendTaskInfo send = state as SendTaskInfo;
lock (ThreadObject)
{
Debug.Write("ThreadSendOne" + " " + send.cmdName + ":" + DateTime.Now.ToString("mm:ss.ffff") + "\r\n");
SendTaskInfo data = state as SendTaskInfo;
byte[] buffData = data.sendData;
serialPort.Write(buffData, 0, buffData.Length);
Debug.Write("ThreadSendTwo" + " " + System.Text.Encoding.ASCII.GetString(buffData) + ":" + DateTime.Now.ToString("mm:ss.ffff") + "\r\n");
Thread.Sleep(300);
}
}
/// <summary>
/// 开启一个线程接收数据
/// </summary>
/// <param name="Obj"></param>
private void ThreadReceive(object state)
{
ReceiveTaskInfo task = state as ReceiveTaskInfo;
List<byte> tmpList = new List<byte>();
Debug.Write("ThreadReceive1" + " " + task.cmdName + ":" + DateTime.Now.ToString("mm:ss.ffff") + "\r\n");
bool lenState = false;
//manulReadEvent.Reset();
//bool fag = manulReadEvent.WaitOne();
//if (!fag) return;
lock (ThreadObject)
{
while (!lenState)
{
if (serialPort.BytesToRead > 0)
{
byte[] buff = new byte[serialPort.BytesToRead];
serialPort.Read(buff, 0, buff.Length);
tmpList.AddRange(buff);
if (tmpList.Count != task.cmdLen)
continue;
else
{
lenState = true;
Debug.Write("ThreadReceive2" + " " + tmpList.Count + ":" + DateTime.Now.ToString("mm:ss.ffff") + "\r\n");
returnBuff.Enqueue(tmpList.GetRange(0, task.cmdLen).ToArray());
tmpList.Clear();
//manulWriteEvent.Set();
}
}
else
break;
}
}
}
/// <summary>
/// 解析数据
/// </summary>
/// <param name="data"></param>
private void WaitAnalysisData(object data)
{
if (!serialPort.IsOpen) return;
ReceiveTaskInfo state = data as ReceiveTaskInfo;
System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(GetData), state);
}
/// <summary>
/// 解析串口数据
/// </summary>
/// <param name="Obj"></param>
private void GetData(object state)
{
if (tab == null || tab.Rows.Count == 0 || returnBuff.Count == 0)
return;
ReceiveTaskInfo task = state as ReceiveTaskInfo;
Debug.Write("GetData:" + task.cmdName + ":" + DateTime.Now.ToString("mm:ss.ffff") + "\r\n");
byte[] buffAll = new byte[0];
lock (QueueObject)
{
Debug.Write("returnBuff.Count:" + returnBuff.Count + ":" + DateTime.Now.ToString("mm:ss.ffff") + "\r\n");
buffAll = returnBuff.Dequeue();
Debug.Write("buffAll.Count:" + buffAll.Length + ":" + DateTime.Now.ToString("mm:ss.ffff") + "\r\n");
string len = string.Empty;
int frameLen = 0;
byte[] buffTemp = new byte[4];
for (int i = 0; i < 4; i++)
{
buffTemp[i] = buffAll[i + 5];
}
len = GetAscByByte(buffTemp);
frameLen = Convert.ToInt16(len, 16) + 8;
if (buffAll.Length < frameLen)
return;
string returnStr = string.Empty;
returnStr = GetAscByByte(buffAll);
Debug.Write(returnStr + ":" + DateTime.Now.ToString("mm:ss.ffff") + "\r\n");
bool fag = analy.GetPtlData(tab, returnStr, ref data);
if (!fag) return;
if (returnData.ContainsKey(task.cmdName.Trim()))
{
returnData.Remove(task.cmdName.Trim());
returnData.Add(task.cmdName.Trim(), data);
}
else
{
returnData.Add(task.cmdName, data);
}
Debug.Write(data + "1:" + DateTime.Now.ToString("mm:ss.ffff") + "\r\n");
if (dataFromPromEventHandle != null)
dataFromPromEventHandle(this, null);
Thread.Sleep(300);
}
}