0

I'm making a flight controller program in C# and this receives data function, the program will run as intended for around 2 minutes before the program crashes and returns the error invalid JSON primitive. I've tried googling around and can't find anything about my issue, as I can't see any problems with the program. The function that deserializes the JSON is here, this is also the line that causes the error and returns the invalid JSON primitive message.

void ReceiveData() //This function is used to listen for messages from the flight simulator
{
    while (true)
    {
        NetworkStream stream = client.GetStream(); //sets the network stream to the client's stream
        byte[] buffer = new byte[256]; //Defines the max amount of bytes that can be sent

        int bytesRead = stream.Read(buffer, 0, buffer.Length);

        if (bytesRead > 0)
        {
            string jsonreceived = Encoding.ASCII.GetString(buffer, 0, bytesRead); //Converts the received data into ASCII for the json variable
            JavaScriptSerializer Deserializer = new JavaScriptSerializer();
            TelemetryUpdate telemetry = Deserializer.Deserialize<TelemetryUpdate>(jsonreceived);
            this.Invoke(new Action(() => { TelemetryReceivedLabel.Text = jsonreceived; })) ;
            Updatelabels(telemetry); //runs the update labels function with the telemetry data as an argument

            lock (@"c:\temp\BlackBox.txt")
            {
                File.AppendAllText(@"c:\temp\BlackBox.txt", "Data Received" + jsonreceived + DateTime.Now.ToString("h:mm:ss tt") + Environment.NewLine); //this appends the json data to the blackbox file
            }
        }
    }
}

The program works completely fine and passes information into variables how I want it too like this I have logged the JSON data t check if the variable names match etc. they all fit correctly.

void Updatelabels(TelemetryUpdate telemetry) //this function updates all the labels with received data
{
    if (this.InvokeRequired) //invokes the telemetryupdatedelegate
    {
        this.Invoke(new TelemetryUpdateDelegate(Updatelabels), telemetry);
        return;
    }
    
    altitudelabel.Text = string.Format("{0:0.00}", telemetry.Altitude);
    speedlabel.Text = string.Format("{0:0.00}", telemetry.Speed);
    pitchlabel.Text = string.Format("{0:0.00}", telemetry.Pitch);
    verticalspeedlabel.Text = string.Format("{0:0.00}", telemetry.VerticalSpeed);
    throttlelabel.Text = string.Format("{0:0.00}", telemetry.Throttle);
    elevatorspeedlabel.Text = string.Format("{0:0.00}", telemetry.ElevatorPitch);

    WarningUpdateEvent?.Invoke(telemetry); //invokes the warning update event
    ReceivedDataGrid.Rows.Insert(0,telemetry.Altitude, telemetry.Speed, telemetry.Pitch, telemetry.VerticalSpeed, telemetry.Throttle, telemetry.ElevatorPitch, telemetry.WarningCode); //populates the datagrid with the received data
    ReceivedDataGrid.AutoResizeColumns(); //resizes the columns to fit properly
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • What if there is more data in your stream than 256 bytes? If so, the JSON would be incomplete and invalid. Would [ReadToEnd](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamreader.readtoend?view=net-7.0) work for you? – Simon Wilson Jan 05 '23 at 14:04
  • @SimonWilson i tried that i increased it to 2048 byte and the program lasts around a minute longer than previously. however it still ends up crashing with the same error – roadgh1256 Jan 05 '23 at 14:28
  • then obviously the stream you are reading is getting larger on each call...what is `client`? the object you get the stream from? All I can think is, as you are appending all text to a file, the stream source may also be doing the same, as in reading from another source that is growing, such as an appended file. (does this make sense?) – Simon Wilson Jan 05 '23 at 14:40
  • Another thing to try....kick out your `jsonreceived` value to a text file...see what is being returned and then examine it. – Simon Wilson Jan 05 '23 at 14:42
  • @SimonWilson I've tried that too and I can't see anything specifically that stands out as irregular. – roadgh1256 Jan 05 '23 at 14:54
  • @roadgh1256 JavaScriptSerializer was obsolete many years ago. Doesn't make any sense to try to fix something. Why don't you try Newtonsoft.Json for example? – Serge Jan 05 '23 at 15:02
  • @Serge its a school project, it has to be done according to the set way they provided. I'm still getting the issue as well and no idea why – roadgh1256 Jan 05 '23 at 15:40
  • 1
    `lock (@"c:\temp\BlackBox.txt")` I'm worried that you think this does something other than what it [actually does](https://stackoverflow.com/a/4193016/1563833). – Wyck Jan 06 '23 at 17:16
  • @Wyck it locks the file, i have multiple threads and functions writing to one file an it would crash with a cross thread operation error, having the lock stopped it crashing – roadgh1256 Jan 07 '23 at 10:23
  • 1
    @roadgh1256, each thread is locking the same object and thus coordinating your threads. But the object you chose has ***nothing*** to do with the file or its filename. You can lock *any* **object** in .NET. You're locking a particular string (strings are objects). It just so happens that in .NET, strings with the same content are also _the same object_, so locking a string is actually locking the one-and-only object associated with that string. But, IMO, It's better to explicitly create an object `object myLock = new object();` and then call `lock (myLock)`. I hope you understand that. – Wyck Jan 07 '23 at 18:20

1 Answers1

0

The issue seems to stem from a memory leak relating to the datagrid.