本人经验之谈,高手勿喷。
软件定时器可以实现严格的时间执行;
线程中使用等待指定毫秒数,并不能达到准确。
1.定时器等到
private void ReadMessages()
{
CAN_OBJ mMsg = new CAN_OBJ();
int sCount = 0;
do
{
uint mLen = 1;
//if (!((ECANDLL.Receive(1, 0, 0, out mMsg, mLen, 1) == ECANStatus.STATUS_OK) ))
if (!(ECANDLL.Receive(1, 0, 0, out mMsg, mLen, 1) == ECANStatus.STATUS_OK))
{
break;
}
if (mLen == 0) break;
if (mMsg.ID == 0) break;
string shows = "POS_Can1Stt_Rece:"+POS_Can1Stt_Rece.ToString() + " mLen:" + mLen .ToString()+ " CAN1 Rece " + " Time:" + DateTime.Now.ToLocalTime().ToString("yyyy/MM/dd-HH.mm.ss.fff") + " " + DD01.can2string((int)mMsg.ID, mMsg.data, mMsg.ExternFlag, mMsg.RemoteFlag, mMsg.DataLen);
//if (PrintRece_Debug == 1)
{ System.Console.Write(shows); }
Can1Stt_Rece[POS_Can1Stt_Rece].TIME = DateTime.Now.ToLocalTime(); //保存接收到CAN报文的时间
Can1Stt_Rece[POS_Can1Stt_Rece].ID = (int)mMsg.ID;
Can1Stt_Rece[POS_Can1Stt_Rece].LEN = mMsg.DataLen;
Can1Stt_Rece[POS_Can1Stt_Rece].IDE = mMsg.ExternFlag;
Can1Stt_Rece[POS_Can1Stt_Rece].RTR = mMsg.RemoteFlag;
Can1Stt_Rece[POS_Can1Stt_Rece].COUNT = 1;
for (int i = 0; i < 8; i++) { Can1Stt_Rece[POS_Can1Stt_Rece].DATA[i] = mMsg.data[i]; }
DD01.cancopy(Can1Stt_Rece[POS_Can1Stt_Rece].ID, Can1Stt_Rece[POS_Can1Stt_Rece].DATA, Can1Stt_Rece[POS_Can1Stt_Rece].IDE, Can1Stt_Rece[POS_Can1Stt_Rece].RTR, Can1Stt_Rece[POS_Can1Stt_Rece].LEN, Can1Stt_Rece[POS_Can1Stt_Rece].TIME, Can1Stt_Rece[POS_Can1Stt_Rece].COUNT,
ref Can1Stt_Show[POS_Can1Stt_Show].ID, ref Can1Stt_Show[POS_Can1Stt_Show].DATA, ref Can1Stt_Show[POS_Can1Stt_Show].IDE, ref Can1Stt_Show[POS_Can1Stt_Show].RTR, ref Can1Stt_Show[POS_Can1Stt_Show].LEN, ref Can1Stt_Show[POS_Can1Stt_Show].TIME, ref Can1Stt_Show[POS_Can1Stt_Show].COUNT); //复制到显示变量
POS_Can1Stt_Rece++; if (POS_Can1Stt_Rece > MAX_RECE) { POS_Can1Stt_Rece = 0; } //防止接收数据越界
POS_Can1Stt_Show++; if (POS_Can1Stt_Show > MAX_RECE) { POS_Can1Stt_Show = 0; } //防止接收数据越界
Count_Can1Rece++;
}
while (sCount < 500);
}
2.线程等待
public void rece_while()
{
while (true)
{
System.Threading.Thread.Sleep(1); //经验:这个延时不能放在循环体的最前面,否则win10闪退
CAN_OBJ mMsg = new CAN_OBJ();//CAN_OBJ[] mMsg = new CAN_OBJ[1024]
if (ECANDLL.Receive(1, 0, 0, out mMsg, 1, 1) == ECANStatus.STATUS_OK)
{
string shows = "CAN1 Rece " + " Time:" + DateTime.Now.ToLocalTime().ToString("yyyy/MM/dd-HH.mm.ss.fff") + " " + DD01.can2string((int)mMsg.ID, mMsg.data, mMsg.ExternFlag, mMsg.RemoteFlag, mMsg.DataLen);
if (PrintRece_Debug == 1) { System.Console.Write(shows); }
Can1Stt_Rece[POS_Can1Stt_Rece].TIME = DateTime.Now.ToLocalTime(); //保存接收到CAN报文的时间
Can1Stt_Rece[POS_Can1Stt_Rece].ID = (int)mMsg.ID;
Can1Stt_Rece[POS_Can1Stt_Rece].LEN = mMsg.DataLen;
Can1Stt_Rece[POS_Can1Stt_Rece].IDE = mMsg.ExternFlag;
Can1Stt_Rece[POS_Can1Stt_Rece].RTR = mMsg.RemoteFlag;
Can1Stt_Rece[POS_Can1Stt_Rece].COUNT = 1;
for (int i = 0; i < 8; i++) { Can1Stt_Rece[POS_Can1Stt_Rece].DATA[i] = mMsg.data[i]; }
DD01.cancopy(Can1Stt_Rece[POS_Can1Stt_Rece].ID, Can1Stt_Rece[POS_Can1Stt_Rece].DATA, Can1Stt_Rece[POS_Can1Stt_Rece].IDE, Can1Stt_Rece[POS_Can1Stt_Rece].RTR, Can1Stt_Rece[POS_Can1Stt_Rece].LEN, Can1Stt_Rece[POS_Can1Stt_Rece].TIME, Can1Stt_Rece[POS_Can1Stt_Rece].COUNT,
ref Can1Stt_Show[POS_Can1Stt_Show].ID, ref Can1Stt_Show[POS_Can1Stt_Show].DATA, ref Can1Stt_Show[POS_Can1Stt_Show].IDE, ref Can1Stt_Show[POS_Can1Stt_Show].RTR, ref Can1Stt_Show[POS_Can1Stt_Show].LEN, ref Can1Stt_Show[POS_Can1Stt_Show].TIME, ref Can1Stt_Show[POS_Can1Stt_Show].COUNT); //复制到显示变量
POS_Can1Stt_Rece++;
POS_Can1Stt_Show++;
Count_Can1Rece++;
}
CAN_OBJ mMsg2 = new CAN_OBJ();//CAN_OBJ[] mMsg = new CAN_OBJ[1024]
if (ECANDLL.Receive(1, 0, 1, out mMsg2, 1, 1) == ECANStatus.STATUS_OK)
{
string shows = "CAN2 Rece " + " Time:" + DateTime.Now.ToLocalTime().ToString("yyyy/MM/dd-HH.mm.ss.fff") + " " + DD01.can2string((int)mMsg2.ID, mMsg2.data, mMsg2.ExternFlag, mMsg2.RemoteFlag, mMsg2.DataLen);
if (PrintRece_Debug == 1) { System.Console.Write(shows); }
Can2Stt_Rece[POS_Can2Stt_Rece].TIME = DateTime.Now.ToLocalTime(); //保存接收到CAN报文的时间
Can2Stt_Rece[POS_Can2Stt_Rece].ID = (int)mMsg2.ID;
Can2Stt_Rece[POS_Can2Stt_Rece].LEN = mMsg2.DataLen;
Can2Stt_Rece[POS_Can2Stt_Rece].IDE = mMsg2.ExternFlag;
Can2Stt_Rece[POS_Can2Stt_Rece].RTR = mMsg2.RemoteFlag;
Can2Stt_Rece[POS_Can2Stt_Rece].COUNT = 1;
for (int i = 0; i < 8; i++) { Can2Stt_Rece[POS_Can2Stt_Rece].DATA[i] = mMsg2.data[i]; }
DD01.cancopy(Can2Stt_Rece[POS_Can2Stt_Rece].ID, Can2Stt_Rece[POS_Can2Stt_Rece].DATA, Can2Stt_Rece[POS_Can2Stt_Rece].IDE, Can2Stt_Rece[POS_Can2Stt_Rece].RTR, Can2Stt_Rece[POS_Can2Stt_Rece].LEN, Can2Stt_Rece[POS_Can2Stt_Rece].TIME, Can2Stt_Rece[POS_Can2Stt_Rece].COUNT,
ref Can2Stt_Show[POS_Can2Stt_Show].ID, ref Can2Stt_Show[POS_Can2Stt_Show].DATA, ref Can2Stt_Show[POS_Can2Stt_Show].IDE, ref Can2Stt_Show[POS_Can2Stt_Show].RTR, ref Can2Stt_Show[POS_Can2Stt_Show].LEN, ref Can2Stt_Show[POS_Can2Stt_Show].TIME, ref Can2Stt_Show[POS_Can2Stt_Show].COUNT); //复制到显示变量
POS_Can2Stt_Rece++;
POS_Can2Stt_Show++;
Count_Can2Rece++;
}
//Console.WriteLine("Can1Stt_Send_Thread.COUNT:{0} Can1Send_TimeNeed_Thread:{1} Can1Send_Space_Thread:{2} Can1Send_SpaceCount_Thread:{3}", Can1Stt_Send_Thread.COUNT, Can1Send_TimeNeed_Thread, Can1Send_Space_Thread, Can1Send_SpaceCount_Thread);
}
}
总结:
以上两种方式均可以实现一直接收数据;
第一种适用对读取速度严格要求的场景‘
第二种适用实时性要求低的场景。