Search code examples
c#multithreadingwinformstimermschart

C# WinForms Trying to Update UI with Timer but without slowing the performance down


so currently I've got an application that has 2 processes. One process is pining, while pinging the process is writing down the results into an array.

Another process is for updating the UI every second with a timer. Whats being update is an mschart to be more exact.

That's how I have set up the timer:

readonly System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();
myTimer.Interval = 1000;
myTimer.Tick += WriteFunction;

Now this is the method that I'm calling every second for refreshing the UI / actually Graph:

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

The method, for updating the chart is inside another class, and looks like this:

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

        chart_holder.Series[0].Points.Clear();

        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)
                {
                    DataPoint point = new DataPoint(i, 0);
                    chart_holder.Series[0].Points.Add(point);
                }
                else
                {
                    DataPoint point = Array.Find(file, element => element.XValue == i);
                    chart_holder.Series[0].Points.Add(point);
                }
            }
            catch(Exception ex)
            {
                MessageBox.Show(Convert.ToString(ex));
            }
        }
    }

Now what I noticed was that if the graphSizing (number that I'm looping through) is kept low, the performance is kinda fine and everything is sync (multiple graphs from UI are updated at same time etc.) like it should be. But as soon as i rise it let's say to like 50 or even 250 (what the goal should be) the UI and Graph updating are being very very slow. It's only updating like every 3s and the UI is in general very laggy and slow.

Does anyone has any advice how I can maintain good performance or where I messed up that the UI is so slow? For further questions or more details feel free to ask.

Thanks a lot for your time and helping.

Greetings C.User


Solution

  • Your code always runs in the UI thread, since System.Windows.Forms.Timer calls the delegate on the UI thread. Even if that where not the case (and you used System.Timer instead), you delegate everything back to the UI with your Invoke call. You need to make sure you prepare the data on another thread first and do as little as possible in the UI thread itself.