C# 我需要按照在后台使用委托同步接收的顺序处理多个数据缓冲区

C# 我需要按照在后台使用委托同步接收的顺序处理多个数据缓冲区,c#,delegates,synchronous,C#,Delegates,Synchronous,需要在后台处理串行端口上接收到的数据,以便在接收时可以在用户窗体上使用/显示解码数据。串行数据消息块有时可以在多个缓冲器中接收。因此,串行数据缓冲区必须按照接收顺序进行处理,以确保所有消息块都是完整的 我正在尝试使用c#中的委托按接收顺序处理多个串行数据缓冲区 当收到数据时,从我的ClassSerialPort调用方法“public static void ReceiveSerialData(byte[]byteBuffer,int length)” 我得到异常“System.NullRefer

需要在后台处理串行端口上接收到的数据,以便在接收时可以在用户窗体上使用/显示解码数据。串行数据消息块有时可以在多个缓冲器中接收。因此,串行数据缓冲区必须按照接收顺序进行处理,以确保所有消息块都是完整的

我正在尝试使用c#中的委托按接收顺序处理多个串行数据缓冲区

当收到数据时,从我的ClassSerialPort调用方法“public static void ReceiveSerialData(byte[]byteBuffer,int length)”

我得到异常“System.NullReferenceException:“对象引用未设置为对象的实例。”“在”caller.EndInvoke(out threadID,result)行上;”

我有两个问题:

  • 如何更正System.NullReferenceException异常

  • 以这种方式使用代理是否会按照接收顺序处理多个串行数据缓冲区

  • 我的代码:

    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