C# WinForms 尝试使用计时器更新 UI 但不会降低性能

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

所以目前我有一个有 2 个进程的应用程序。一个进程是 pining,而 ping 进程是将结果写到一个数组中。

另一个过程是用定时器每秒更新一次UI。更新的是更准确的 mschart。

我就是这样设置定时器的:

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

现在这是我每秒调用的方法来刷新 UI / 实际上是图形:

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

更新图表的方法在另一个 class 中,看起来像这样:

    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));
            }
        }
    }

现在我注意到,如果 graphSizing(我正在循环的数字)保持较低,性能还不错,一切都是同步的(来自 UI 的多个图表同时更新等)就像它应该的那样。但是一旦我上升,让我们说喜欢 50 甚至 250(目标应该是什么),UI 和图表更新非常非常慢。它只像每 3 秒更新一次,UI 通常非常滞后和缓慢。

有没有人对我如何保持良好的性能有任何建议,或者我在哪里搞砸了 UI 太慢了?如有其他问题或更多详情,请随时提出。

非常感谢您的宝贵时间和帮助。

你好C.User

您的代码始终在 UI 线程中运行,因为 System.Windows.Forms.Timer 在 UI 线程上调用委托。即使不是这种情况(并且您使用 System.Timer 代替),您也可以通过 Invoke 调用将所有内容委托回 UI 。您需要确保首先在另一个线程上准备数据,并尽可能少地在 UI 线程本身中执行操作。