Hi i have create a program in C# to receive a string of ASCII the string is an XML markup.
The computer i receive the data from i have no control over and does not accept a response it sends out data on the COM port about every 10 mins
The Console app i have collects and stores this data but it does not always work i would say about 50% of the time data is missing like a packet or byte was lost and the XML string wont read into XmlDocument
I have been trying for about a week now to make this more stable but this is my first time in C# and would like some help is there anyway to improve this.
CODE
  class SerialPortProgram : IDisposable
  {
    // Create the serial port with basic settings
    private SerialPort port = new SerialPort("COM1",
       115200, Parity.None, 8, StopBits.One);
    string sBuffer = null;
    string filePath1 = @"C:\Data\data1.xml";
    string filePath2 = @"C:\Data\data2.xml";
    [STAThread]
    static void Main(string[] args)
    {
        // Instatiate this class
        new SerialPortProgram();
    }
    private SerialPortProgram() 
    {
        Console.WriteLine("Started Data Monitoring:");
        //Attach a method to be called when there
        //is data waiting in the port's buffer
        port.ReadBufferSize = 20971520;
        port.ReceivedBytesThreshold = 1;
        port.DataReceived += new SerialDataReceivedEventHandler(Port_DataReceived);
        //Begin communications
        port.Open();
        //Enter an application loop to keep this thread alive
        Application.Run();
    }
    private void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        //Show all the incoming data in the port's buffer
        SerialPort sp = (SerialPort)sender;
        sBuffer += sp.ReadExisting();
        if (sBuffer.Length > 26000) // check the file size
        {
            if (sBuffer.Substring(sBuffer.Length - 6) == "</xml>") // check for end of file
            {
                Console.WriteLine("Found: Processing...");
                //Thread.Sleep(1000);
                ProcessXML();
                sBuffer = null;
                Console.WriteLine("Done!");
                DateTime now = DateTime.Now;
                Console.WriteLine(now);
                Console.WriteLine("Monitoring...");
            }
            else
            {
                Console.WriteLine("Still Receiving Data: " + sBuffer.Length);
            }
        }
        else
        {
            Console.WriteLine("Receiving Data: " + sBuffer.Length);
        }
    }
 private void ProcessXML()
    {
        XmlDocument xmlDoc = new XmlDocument();
        try
        {
            xmlDoc.LoadXml("<wrapper>" + sBuffer + "</wrapper>");
            int index = 0;
            XmlNodeList xnl = xmlDoc.SelectNodes("wrapper/xml");
            foreach (XmlNode node in xnl)
            {
                // Console.WriteLine(index.ToString());
                if (index == 0)// xml file 1
                {
                    using (XmlReader r = new XmlNodeReader(node))
                    {
                        DataSet ds = new DataSet();
                        ds.ReadXml(r);
                        ds.WriteXml(filePath1);
                        Console.WriteLine("NEW Data1");
                        ds.Dispose();
                        var db = new Database();
                        db.SaveMetersToDatabase(ds);
                    }
                }
                else if (index == 1)// xml file 2
                {
                    using (XmlReader r1 = new XmlNodeReader(node))
                    {
                        DataSet dst = new DataSet();
                        dst.ReadXml(r1);
                        dst.WriteXml(filePath2);
                        Console.WriteLine("NEW Data2");
                        dst.Dispose();
                    }
                }
                index++;
            }
        }
        catch
        {
            Console.WriteLine("Error: in data");
            try
            {
                string now = DateTime.Now.ToString("yyyyMMddHHmmss");
                System.IO.File.WriteAllText(@"C:\Data\log" + now + ".xml", "<wrapper>" + sBuffer + "</wrapper>");
            }
            catch
            {
                Console.WriteLine("Failed to write to log");
            }
        }
    }
    protected virtual void Dispose(bool disposing)
    {
        if (disposing && port != null)
        {
            port.Dispose();
            port = null;
        }
    }
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
  }
}
UPDATED CODE:
  private void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        //Show all the incoming data in the port's buffer
        SerialPort sp = (SerialPort)sender;
        sBuffer += sp.ReadExisting();
        new Thread(() =>
        {
            Thread.CurrentThread.IsBackground = true;
            if (sBuffer.Length > 25000) // check the file size
            {
                if (sBuffer.Substring(sBuffer.Length - 6) == "</xml>") // check for end of file
                {
                    Console.WriteLine("Found: Processing...");
                    Task.Run(() =>
                    {
                        ProcessXML();
                        sBuffer = null;
                        Console.WriteLine("Done!");
                        DateTime now = DateTime.Now;
                        Console.WriteLine(now);
                        Console.WriteLine("Monitoring...");
                    });
                }
                else
                {
                    Console.WriteLine("Still Receiving Data: " + sBuffer.Length);
                }
            }
            else
            {
                Console.WriteLine("Receiving Data: " + sBuffer.Length);
            }
        }).Start();
    }
UPDATE
still having this issue could it be possible that the sending computer sometimes does not send all the data or there is packet loss i have tried everything i have tried this new code below using Serial Port BaseStream BeginRead
  private SerialPortProgram() 
    {
        Console.WriteLine("Started Data Monitoring:");
        //Attach a method to be called when there
        try
        {
            Port.BaudRate = 115200;
            Port.DataBits = 8;
            Port.Parity = Parity.None;
            Port.StopBits = StopBits.One;
            Port.Handshake = Handshake.None;
            Port.DtrEnable = true;
            Port.NewLine = Environment.NewLine;
            Port.ReceivedBytesThreshold = 2048;
            Port.Open();
            byte[] buffer = new byte[35000];
            Action StartRead = null;
            StartRead = () => {
                Port.BaseStream.BeginRead(buffer, 0, buffer.Length, async (IAsyncResult ar) =>
                {
                    try
                    {
                        int actualLength = Port.BaseStream.EndRead(ar);
                        byte[] received = new byte[actualLength];
                        Buffer.BlockCopy(buffer, 0, received, 0, actualLength);
                        await Task.Run(() =>
                        {
                            sBuffer += Encoding.ASCII.GetString(received);
                            CheckBuffer();
                        });
                    }
                    catch (Exception exc)
                    {
                        Console.WriteLine(exc);
                    }
                    StartRead();
                }, null);
            };
            StartRead();
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error accessing port." + ex);
            Port.Dispose();
            Application.Exit();
        }
        //Enter an application loop to keep this thread alive
        Application.Run();
    }
    private void CheckBuffer()
    {
        if (sBuffer != null && sBuffer.Length > 26000) // check the file size
        {
            if (sBuffer.Substring(sBuffer.Length - 6) == "</xml>") // check for end of file
            {
                new Thread(async () =>
               {
                   Console.WriteLine("Found: Processing...");
                   await Task.Run(() => ProcessXML());
                   sBuffer = null;
                   Console.WriteLine("Done!");
                   DateTime now = DateTime.Now;
                   Console.WriteLine(now);
                   Console.WriteLine("Monitoring...");
               }).Start();
            }
            else
            {
                Console.WriteLine("Still Receiving Data: " + sBuffer.Length);
            }
        }
        else if (sBuffer != null && sBuffer.Length > 0)
        {
            Console.WriteLine("Receiving Data: " + sBuffer.Length);
        }
    }
 
     
    