I am trying to collect real time data from an GPS/IMU combination and display the information continuously in a WinForm Label. I will be getting the GPS/IMU data in the main program and then starting a thread to display the data in real time while the main program continues to collect the data. I was able to make this work in a short test case but when I expanded the test to put the thread code in a separate class I am having problems. First the code and then I'll cover the issues:
Data is placed in properties in a class-the class code for this is:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Thread_Test_Sending_Data_to_Thread_Function
{
public class FormData
{
public int Label1Data;
public int Label2Data;
}
}
The main program to collect the data and start the thread which is currently only using set data is:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
namespace Thread_Test_Sending_Data_to_Thread_Function
{
public partial class Form1 : Form
{
public Form1()
{
int i;
InitializeComponent();
FormData FormData1 = new FormData();
Thread1 MyThread = new Thread1();
for (i = 1; i < 5; i++)
{
FormData1.Label1Data = i;
FormData1.Label2Data = i * 10;
Thread WriteScreen = new Thread(delegate ()
{
MyThread.FormWriteMethod(FormData1, TestLabel1);
});
WriteScreen.Start();
Thread.Sleep(1000);
}
}
}
}
The code for the thread class is:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Diagnostics;
using System.Windows.Forms;
namespace Thread_Test_Sending_Data_to_Thread_Function
{
public class Thread1
{
int testInt1;
int testInt2;
int test;
private delegate void SetLabelTextDelegate(FormData InputClass);
public void FormWriteMethod(FormData InputClass, Label lbl)
{
testInt1 = InputClass.Label1Data;
testInt2 = InputClass.Label2Data;
UpdateLabel(lbl, InputClass.Label1Data.ToString());
}
void UpdateLabel(Label lbl, string text)
{
if (lbl.InvokeRequired)
{
lbl.Invoke(new Action<Label, string>(UpdateLabel), new object[] { lbl, text });
}
else
{
lbl.Text = text;
}
}
}
Based on using the debugger in VS I am pretty sure the thread is being properly initiated in that the code in the thread runs. When I first started trying to do this I didn't pass the label for the WinForm Label the thread and trying the InvokeRequired method resulted in a InvokeRequired not in context. I added passing the label to the thread and then lbl.InvokeRequired compiled. However, it always indicates false and the lbl.Text=text; loads the label but the label contents are not displayed until the main program exits. This implies that even after starting the new thread that the thread is still in the main thread that controls the GUI. Have been working on this for days with no positive results. Would appreciate any help.
What I have tried:
I tried moving the InvokeRequired code to the FormWriteMethod to see if somehow calling a second method somehow got out of the display thread and back to the main thread but that didn't seem to help.