Search code examples
c#multithreadingwinformstimermschart

C# WinForms Trying to keep timeline synchronized


Hello I'm trying to update my chart(s) every second, all chart(s) should be always at the same time. For better understanding I'll include an image but first off I'm gonna explain what actually happens.

So I'm ping requests are sent, every time an result is there, it writes it down in an data point array called file. Everything fine, works as expected.

At the same time, two timers are running, one timer calls a method that prepares the data (let's say at a specific time no data is found in the array -> it should just set value 0). The prepared data is than in a buffer.

The second timer is updating the UI and reading from the tempData but this isn't quite working as expected or wished.

Timers:

myTimer.Interval = 1000;
myTimer.Tick += FileReadFunction;

aTimer.Elapsed += new System.Timers.ElapsedEventHandler(prepData);
aTimer.Interval = 1000;

Button Click which starts timers:

private void _tbStartAll_Click(object sender, EventArgs e)
        {
            lock (_hosts)
            {
                foreach (HostPinger hp in _hosts)
                    hp.Start();

                myTimer.Start();
                aTimer.Enabled = true;
            }
        }

Method for preparing Data in Form Class:

 public void prepData(object objectInfo, EventArgs e)
        {
            foreach (NetPinger.source.AddGraph b in graphList)
            {
                b.prepareData();
            }
        }

Prep Data Method:

public void prepareData()
        {
            double unixTimestamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;

            for (double i = unixTimestamp; unixTimestamp - graphSizing < i; i--)
            {
                bool exists;
                try
                {
                    exists = Array.Exists(file, element => element.XValue == i);
                    exists = true;
                }
                catch
                {
                    exists = false;
                }
                try
                {
                    if (exists == false)
                    {
                        TempBuffer = TempBuffer.Skip(1).Concat(new DataPoint[] { new DataPoint(i, 0) }).ToArray();
                    }
                    else
                    {
                        DataPoint point = Array.Find(file, element => element.XValue == i);
                        TempBuffer = TempBuffer.Skip(1).Concat(new DataPoint[] { (point) }).ToArray();
                    }
                }
                catch (Exception ex)
                {
                    //just for debugging...
                }
            }
        }

File Read Method in Form Class:

private void FileReadFunction(object objectInfo, EventArgs e)
        {
            foreach (NetPinger.source.AddGraph b in graphList)
            {
                b.fileRead();
            }
        }

Method FileRead / Update Chart:

 public void fileRead()
        {
            //double unixTimestamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
            chart_holder.Series[0].Points.Clear();
            foreach (DataPoint a in TempBuffer)
            {
                chart_holder.Series[0].Points.Add(a);
            }
}

Image Example of what I mean with time synchronization: enter image description here

I'm kinda out of ideas why it's not working out, is it because a thread is faster than another? Or what is the reason and how could I fix it? I'm very thankful for your help.

Greetings C.User


Solution

  • I solved the problem by changing the code a bit. To keep it synchronized I prepare the data first, before displaying it at all. After the data is prepared than all the data is getting displayed. Also I only use one timer now instead of two.