C# 我需要按照在后台使用委托同步接收的顺序处理多个数据缓冲区
需要在后台处理串行端口上接收到的数据,以便在接收时可以在用户窗体上使用/显示解码数据。串行数据消息块有时可以在多个缓冲器中接收。因此,串行数据缓冲区必须按照接收顺序进行处理,以确保所有消息块都是完整的 我正在尝试使用c#中的委托按接收顺序处理多个串行数据缓冲区 当收到数据时,从我的ClassSerialPort调用方法“public static void ReceiveSerialData(byte[]byteBuffer,int length)” 我得到异常“System.NullReferenceException:“对象引用未设置为对象的实例。”“在”caller.EndInvoke(out threadID,result)行上;” 我有两个问题:C# 我需要按照在后台使用委托同步接收的顺序处理多个数据缓冲区,c#,delegates,synchronous,C#,Delegates,Synchronous,需要在后台处理串行端口上接收到的数据,以便在接收时可以在用户窗体上使用/显示解码数据。串行数据消息块有时可以在多个缓冲器中接收。因此,串行数据缓冲区必须按照接收顺序进行处理,以确保所有消息块都是完整的 我正在尝试使用c#中的委托按接收顺序处理多个串行数据缓冲区 当收到数据时,从我的ClassSerialPort调用方法“public static void ReceiveSerialData(byte[]byteBuffer,int length)” 我得到异常“System.NullRefer
using ClassSerialPort;
using TheUserForm;
using System;
using System.Threading;
using System.Diagnostics;
using System.Text;
namespace TheUserForm
{
class ClsReceiveSerialData
{
// SerialPort property
private ClsSerialPort serialPort;
public ClsSerialPort SerialPor`enter code here`t
{
get
{
return serialPort;
}
set
{
serialPort = value;
}
}
public static void ReceiveSerialData(byte[] byteBuffer, int length)
{
int i;
int threadID = 0;
#if (TEST)
StringBuilder sb = new StringBuilder(byteBuffer.Length * 2);
i = 0;
foreach (byte b in byteBuffer)
{
//convert a byte to a hex string
sb.AppendFormat("{0:x2}", b);
i++;
}
//write the debuf string to the output window
Debug.WriteLine("byteBuffer[" + (i - 1) + "] = " + sb.ToString());
#endif
// create an instance of a delegate class
ClsProcessData ad = new ClsProcessData();
// Create the delegate.
AsyncProcessData caller =
AsyncProcessData(ad.BeginProcessingData);
// Initiate the asychronous call.
IAsyncResult result =
caller.BeginInvoke(byteBuffer, length, out threadID, null, null);
// Call EndInvoke to wait for the asynchronous call to complete,
// and to retrieve the results.
caller.EndInvoke(out threadID, result);
}
}
class ClsProcessData
{
bool gotFirstFEcode = false;
bool gotSecondFEcode = false;
bool gotCtrlrCIV = false;
bool okToSaveCommandBytes = false;
bool gotEndOfMessageCode = true;
byte[] commandData;
int commandIndex = 0;
public void BeginProcessingData(byte[] data, int byteCount,
out int threadId)
{
lock (this)
{
int i;
threadId = Thread.CurrentThread.ManagedThreadId;
#if (TEST)
Debug.WriteLine(
String.Concat("BeginProcessingData threadID = ",
Convert.ToString(threadId)));
#endif
//find a preamble
i = 0;
while (i < byteCount)
{
// have we completed processing the current message?
if (gotEndOfMessageCode)
{
//reset the preamble detection booleans
gotFirstFEcode = false;
gotSecondFEcode = false;
gotCtrlrCIV = false;
okToSaveCommandBytes = false;
gotEndOfMessageCode = false;
} // If
//can we save a command byte now?
if (okToSaveCommandBytes)
{
//go save a command byte
i = ExtractCommand(data, i, byteCount);
//reset the preamble detection booleans
gotFirstFEcode = false;
gotSecondFEcode = false;
gotCtrlrCIV = false;
okToSaveCommandBytes = false;
gotEndOfMessageCode = false;
} // If
//have we found the radio//s civ address?
if (gotCtrlrCIV && (data[i] ==
ClsConstants.CTRLR_DEFAULT_CIV_ADDR))
{
//we are ok to start saving command bytes
okToSaveCommandBytes = true;
} // If
//do we have both FE codes of the preamble and not
another extraneous FE code in the buffer
if (gotSecondFEcode && (data[i] ==
ClsConstants.CTRLR_DEFAULT_CIV_ADDR))
{
gotCtrlrCIV = true;
} // If
if (gotFirstFEcode && (data[i] ==
ClsConstants.PREAMBLE_CODE))
{
gotSecondFEcode = true;
} // If
//do we have the first preamble code?
if ((data[i] == ClsConstants.PREAMBLE_CODE) &&
(!gotSecondFEcode))
{
gotFirstFEcode = true;
//reset } // of message boolean
gotEndOfMessageCode = false;
} // If
//increment the array index
i++;
} // while
}
}
// ExrtractCommand returns an updated index value
private int ExtractCommand(byte[] data, int index, int byteCount)
{
int i = index;
while ((i < byteCount) && (!gotEndOfMessageCode))
{
if (data[i] == ClsConstants.END_OF_MESSAGE_CODE)
{
//set the end of message flag
gotEndOfMessageCode = true;
//Process the command
ProcessCommand(commandData, commandIndex);
}
else
{
//save a command byte
commandData[commandIndex] = data[i];
//increment to the next command index
commandIndex++;
} // If
//increment the data array index
i++;
} // while
return i;
} // void
}
使用ClassSerialPort;
使用用户表单;
使用制度;
使用系统线程;
使用系统诊断;
使用系统文本;
命名空间用户窗体
{
类ClsReceiveSerialData
{
//串行端口属性
专用ClsSerialPort串行端口;
public ClsSerialPort SerialPor`在此处输入代码`t
{
得到
{
返回串口;
}
设置
{
串行端口=值;
}
}
公共静态void ReceiveSerialData(字节[]byteBuffer,整数长度)
{
int i;
int-threadID=0;
#如果(测试)
StringBuilder sb=新StringBuilder(byteBuffer.Length*2);
i=0;
foreach(字节缓冲区中的字节b)
{
//将字节转换为十六进制字符串
sb.附录格式(“{0:x2}”,b);
i++;
}
//将debuf字符串写入输出窗口
WriteLine(“byteBuffer[”+(i-1)+“]=”+sb.ToString());
#恩迪夫
//创建委托类的实例
ClsProcessData ad=新的ClsProcessData();
//创建委托。
AsyncProcessData调用者=
AsyncProcessData(ad.BeginProcessingData);
//启动非同步呼叫。
IAsyncResult结果=
BeginInvoke(byteBuffer,length,out-threadID,null,null);
//调用EndInvoke以等待异步调用完成,
//并检索结果。
EndInvoke(out threadID,result);
}
}
类ClsProcessData
{
bool-gotFirstFEcode=false;
bool-gotSecondFEcode=false;
bool-gotCtrlrCIV=false;
bool-okToSaveCommandBytes=false;
bool gotEndOfMessageCode=true;
字节[]命令数据;
int commandIndex=0;
public void BeginProcessingData(字节[]数据,整数字节计数,
out int threadId)
{
锁(这个)
{
int i;
threadId=Thread.CurrentThread.ManagedThreadId;
#如果(测试)
Debug.WriteLine(
String.Concat(“BeginProcessingData threadID=”,
Convert.ToString(threadId));
#恩迪夫
//找到序言
i=0;
while(i