I'm writing a program that reads every second data from a serialPort and save it in a textfile/show it on GUI. The reading starts and end with an buttonclick.
I tried some different timers to solve this but every timer brings some trouble(see below).
My tryouts:
serialPort1.ReadTimeout = 2000;
System.Timers.Timer:
private void timer1_Tick(object sender, EventArgs e)
{
if (!serialPort1.isOpen)
{
serialPort1.Open();
}
serialPort1.WriteLine("INFO"); //Send data command
string data = serialPort1.ReadLine();
serialPort.Close();
editData(data); //Method for GUI update and textfile log
}
Can easily started and stopped with timer1.Start() and timer1.Stop(). The problem is, System.Timers.Timer runs on GUI Threard and freezes the GUI while serialPort.read and serialPort.Close() is called.
Backgroundworker:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
while (backgroundWorker1.CancellationPending == false)
{
if (!serialPort1.isOpen)
{
serialPort1.Open();
}
serialPort1.WriteLine("INFO");
string data = serialPort1.ReadLine();
serialPort.Close();
Invoke((MethodInvoker)(() => editData(data)); //Method for GUI update and textfile log
}
}
Runs asynchronlly. I need to run the programm ~every second.
System.Timers.Timer calls Backgroundworker:
private void timer1_Tick(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
if (!serialPort1.isOpen)
{
serialPort1.Open();
}
serialPort1.WriteLine("INFO");
string data = serialPort1.ReadLine();
serialPort.Close();
Invoke((MethodInvoker)(() => editData(data)); //Method for GUI update and textfile log
}
This works fine until the data reading process takes longer or a serialPort.readTimeout occur. Backgroundworker can only run once. So I think this isn't an option.
System.Threading.Timers:
System.Threading.Timer timer;
timer = new System.Threading.Timer(_ => readSerialPort(), null, 0, 950);
private void readSerialPort()
{
if (!serialPort1.isOpen)
{
serialPort1.Open();
}
serialPort1.WriteLine("INFO");
string data = serialPort1.ReadLine();
serialPort.Close();
Invoke((MethodInvoker)(() => editData(data)); //Method for GUI update and textfile log
}
This works fine but the problem is, I can't stop and restart the reading.
Do anyone have an idea which timer I should use in this case?
System.Threading.Timer- just useTimer.Change(). Thus, I would recommend that you use this timer.