【问题标题】:Threading data visualization and timers线程数据可视化和计时器
【发布时间】:2020-11-17 04:39:04
【问题描述】:

我想知道实际问题的最佳解决方案是什么。 我没有在这个小项目中使用任何线程。

这是一个简单的 UI 在固定计时器上从串口轮询数据。

数据经过分析、过滤,然后显示在折线图上。

当表单在桌面上移动时,除了数据轮询“挂起”(即没有被执行、没有错误或任何东西)之外,一切都工作正常。

我不一定需要在移动表单时更新图表,但我至少希望计时器在移动时仍然滴答作响(以便数据轮询继续)。

我的计时器声明如下:

private System.Windows.Forms.Timer timer1;

我自己没有定义任何线程,但我的理解是计时器滴答是在单独的线程上发生的。对吗?

我正在处理这样的计时器滴答事件。

private void timer1_Tick(object sender, EventArgs e)
{
    if (chkBoxPosition.Checked)
    {
        tBoxPosition.Text = ExecuteCommand("r 1\n", tBoxPosition.Text, false, false);
        Axis.position = TryParseDouble(Axis.position, tBoxPosition.Text);
    }
}

我在这次活动中有更多东西(图表)。

它工作得很好,但是当我在桌面上拖动 UI winform 时,它会暂时“冻结”控件,直到我放开 UI。它不会崩溃或任何事情,只是在我移动窗口时不会刷新。

就控件而言并不是什么大不了的事,但是,我刚刚意识到整个线程或计时器也挂起,至于我按住鼠标按钮拖动窗口的整个时间似乎什么都没有发生。

【问题讨论】:

  • 你能发布一些代码吗?否则,恐怕您的问题可能会被关闭......
  • 我会在表单上放置一个 BackgroundWorker 控件,并通过无限循环和 Sleep() 调用在 DoWork() 处理程序中进行轮询。更新数据后,使用 ReportProgress() 触发 ProgressChanged() 事件,这样可以安全地更新折线图。
  • 不要在 UI 线程中做非 UI 工作。这样做可以让您的后台工作阻止 UI 线程更新,并允许 UI 更新阻止您的后台工作运行。
  • 不,System.Windows.Forms.Timer 在 UI 线程上运行。

标签: c# multithreading winforms timer


【解决方案1】:

这个问题没有说明正在使用什么图表包,所以我猜是.Net的内置包。

后台工作人员是一个不错的选择,但它相当老派,并且比使用 async Task 需要更多的实现。

注意: 唯一可以使用async void 是在顶级事件处理程序上,否则你应该使用async Task,见this

我这样做是为了让复选框启用和禁用计时器,不确定它在您的应用中的作用。

这里有 2 个版本的代码,v1 是在 ExecuteCommand 完成后更新文本框的位置,而 v2 是在 ExecuteCommnad 方法内更新文本框的位置。

版本 1:(在计时器滴答时更新文本)

 public partial class Form1 : Form
    {
        Series Series1 { get; set; }
        int val = 0;

        public Form1()
        {
            InitializeComponent();
            timer1.Interval = 2000;
            chart1.Series.Clear();

            Series1 = new Series
            {
                Name = "Series1",
                Color = System.Drawing.Color.Green,
                IsVisibleInLegend = false,
                IsXValueIndexed = true,
                ChartType = SeriesChartType.Line
            };
            this.chart1.Series.Add(Series1);
        }

        private async void timer1_Tick(object sender, EventArgs e)
        {
            tBoxPosition.Text = await ExecuteCommand("r 1\n", tBoxPosition.Text, false, false);
            tBoxPosition.Select(tBoxPosition.Text.Length - 1, 0);
            tBoxPosition.ScrollToCaret();
        }

        //not sure what you are doing her but lets say its something that takes some time..maybe a data fetch of some kind
        async Task<string> ExecuteCommand(string str, string text, bool value1, bool value2)
        {                
            StringBuilder returnString = new StringBuilder(text);
            for (int i = 0; i < 10; i++)
            {
                await Task.Delay(100);

                returnString.AppendLine($"value : {val++}");
                Series1.Points.AddXY(i, (i + i + i));
            }
            return returnString.ToString();
        }

        private void chkBoxPosition_CheckedChanged(object sender, EventArgs e)
        {
            if (chkBoxPosition.Checked)
                timer1.Enabled = true;
            else
                timer1.Enabled = false;
        }
    }

版本 2:(更新执行方法中的文本框和图表)

 private async void timer1_Tick(object sender, EventArgs e)
        {
            await ExecuteCommand("r 1\n", tBoxPosition.Text, false, false);

        }

        //not sure what you are doing her but lets say its something that takes some time..maybe a data fetch of some kind
        async Task ExecuteCommand(string str, string text, bool value1, bool value2)
        {
            for (int i = 0; i < 10; i++)
            {
                await Task.Delay(100);

                Series1.Points.AddXY(i, (i + i + i));
                tBoxPosition.Text += $"value : {val++} {Environment.NewLine}";
                tBoxPosition.Select(tBoxPosition.Text.Length - 1, 0);
                tBoxPosition.ScrollToCaret();
            }
        }

【讨论】:

  • 感谢您的彻底回复!我今天将尝试实施任一解决方案!谢谢!
  • 我选择尝试改用 System.Timers.Timer 并且效果很好(我已经确保我的计时器事件没有调用任何 UI 控件,而是使用了标志和变量)。再次感谢您
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-05
  • 1970-01-01
  • 2010-09-11
  • 1970-01-01
  • 2020-03-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多