【问题标题】:C# WinForms Trying to Update UI with Timer but without slowing the performance downC# WinForms 尝试使用 Timer 更新 UI 但不会降低性能
【发布时间】:2018-05-29 07:48:02
【问题描述】:

所以目前我有一个有 2 个进程的应用程序。一个进程正在 ping,而 ping 进程正在将结果写入数组。

另一个过程是使用计时器每秒更新一次 UI。更准确地说,正在更新的是一个 mschart。

这就是我设置计时器的方式:

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

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

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

用于更新图表的方法在另一个类中,如下所示:

    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

【问题讨论】:

  • System.Windows.Forms.Timer 运行在 gui 线程上。所以调用在这里没用。这就是为什么它不能减轻 GUI 线程的负担。如果您想同时加载多个文件,请查看Parallel.Foreach
  • in private void WriteFunction(object objectInfo, EventArgs e) 的目的参数是什么?
  • @Amit 我添加了参数,以便可以使用计时器运行该方法。
  • 每次通过循环时,在循环内声明变量时都会产生成本。特别是当您需要使用new()command 创建它时。
  • 当您对窗体或控件进行大量更新时,例如在循环中,Windows 不会立即为您执行每个更新,而是等待一些中间时间。您可以随时通过Update()statement 强制执行此操作,这将使您的表单看起来更具响应性,但会再次减慢循环速度

标签: c# multithreading winforms timer mschart


【解决方案1】:

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

【讨论】:

  • 感谢您的回答!我将尝试用这个建议解决我的问题。 “准备数据”是指循环文件,对吗?
  • @C.User:正确,并在那里进行所有处理(例如更新表的数据点)
  • 如果 chart_holder.Series[0].Points 依赖于 gui 线程更新,之后可能会添加多个点。所以先处理所有的点,然后批量添加。
猜你喜欢
  • 1970-01-01
  • 2013-01-20
  • 2016-02-25
  • 1970-01-01
  • 2020-12-21
  • 1970-01-01
  • 1970-01-01
  • 2015-07-01
  • 2018-12-12
相关资源
最近更新 更多