首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >实时图表性能问题c# winform

实时图表性能问题c# winform
EN

Stack Overflow用户
提问于 2020-02-12 16:39:32
回答 1查看 769关注 0票数 1

我目前正在使用liveChart绘制一个3值的实时图形:一个位置,一个载荷和一个变形。该程序基于Doli.DoPE库(专有dll)。

MainForm.cs中,每当传感器记录一个新值时(每毫秒左右)都会触发一个事件。

代码语言:javascript
运行
复制
public void Initialisation()
{
   //...    
   MyEdc.Eh.OnDataHdlr += new DoPE.OnDataHdlr(OnData)
   //...
}

使用

代码语言:javascript
运行
复制
private int OnData(ref DoPE.OnData Data, object Parameter)
{
    DoPE.Data Sample = Data.Data;
    if (Data.DoPError == DoPE.ERR.NOERROR)
    {
        Int32 Time = Environment.TickCount;
        if ((Time - LastTime) >= 250 /*ms*/)
        {
            // Send the data from the ondata handler inside of a global list
            ListData.time.Add(Sample.Time);
            ListData.position.Add(Sample.Sensor[(int)DoPE.SENSOR.SENSOR_S]);
            ListData.load.Add(Sample.Sensor[(int)DoPE.SENSOR.SENSOR_F]);
            ListData.extend.Add(Sample.Sensor[(int)DoPE.SENSOR.SENSOR_E]);

            Thread ThForUpdateChart = new Thread(() =>
            {
                if (NewINstanceOfChart != null)
                { NewINstanceOfChart.UpdateValues(ListData.time.Last(), ListData.position.Last(),ListData.load.Last(), ListData.extend.Last()); }
            });
            ThForUpdateChart.Start();
            LastTime = Time;
        }
    }
    return 0;
}

函数UpdateValues是通过单击按钮事件在MainForm中调用的第二个表单RealTimeChart.cs的一部分:

代码语言:javascript
运行
复制
private void btnGraph_Click(object sender, EventArgs e)
{
    var thread = new Thread(() =>
    {
        NewINstanceOfChart = new RealTimeChart(ListData);
        NewINstanceOfChart.Show();
    });
    thread.Start();
}

表格RealTimeCharts.cs是这样简化的:

代码语言:javascript
运行
复制
public RealTimeChart(Globals ListData)
{
    InitializeComponent();

    //measures = ListData;

    ListPosition = new ChartValues<ObservablePoint>();
    for (int i = 0; i < measures.load.Count(); i++)
    {
        ListPosition.Add(new ObservablePoint
        {
            X = measures.time[i],
            Y = measures.position[i]
        });
    }
    ListLoad = new ChartValues<ObservablePoint>();
    for (int i = 0; i < measures.load.Count(); i++)
    {
        ListLoad.Add(new ObservablePoint
        {
            X = measures.time[i],
            Y = measures.load[i]
        });
    }

    ListExtend = new ChartValues<ObservablePoint>();
    for (int i = 0; i < measures.load.Count(); i++)
    {
        ListExtend.Add(new ObservablePoint
        {
            X = measures.time[i],
            Y = measures.extend[i]
        });
    }

    resultChart.Series.Add(new LineSeries
    {
        LineSmoothness = 0,
        Values = ListPosition,
        PointGeometrySize = 2,
        StrokeThickness = 4
    });


    SetXAxisLimits();

}

UpdateValues函数的定义如下:

代码语言:javascript
运行
复制
        public void UpdateValues(double time, double position, double load, double extend)
        {
            measures.time.Add(time-measures.TareTime);
            measures.position.Add(position);
            measures.load.Add(load);
            measures.extend.Add(extend);

            UpdateEnabledSequencialPartToTrue();

        }



        public void UpdateEnabledSequencialPartToTrue()
        {
            if (this.InvokeRequired)
                BeginInvoke(new System.Action(() => this.InternalUpdateEnabledSequencialPartToTrue()));
            else
                InternalUpdateEnabledSequencialPartToTrue();
        }
        private void InternalUpdateEnabledSequencialPartToTrue()
        {
            try
            {
                ListPosition.Add(new ObservablePoint
                {
                    X = measures.time.Last(),
                    Y = measures.position.Last()
                });

                ListLoad.Add(new ObservablePoint
                {
                    X = measures.time.Last(),
                    Y = measures.load.Last()
                });

                ListExtend.Add(new ObservablePoint
                {
                    X = measures.time.Last(),
                    Y = measures.extend.Last()
                });

                //LineSeries plot = new LineSeries();
                SetXAxisLimits();

                // lets only use the last 14400 values (1h long recording, 14400 values at frequency of 1 record very 250ms, see OnData function MainForm
                if (measures.time.Count > 14400)
                {
                    ListPosition.RemoveAt(0);
                    ListLoad.RemoveAt(0);
                    ListExtend.RemoveAt(0);
                }
            }
            catch (NullReferenceException) { }
        }

一分钟后,节目开始显得很滞后。我尝试将第二个winform (RealTimeCharts)放在另一个线程上,这样MainForm就不会滞后(它正在引导一台机器,它必须响应),但没有成功。

我想知道整个事情是滞后的,因为代码太糟糕了,或者是否是liveChart达到了(免费)的极限。你会建议另一种方法来绘制实时数据吗?

EN

Stack Overflow用户

回答已采纳

发布于 2020-02-12 16:47:40

中,每当传感器记录一个新值时(每毫秒左右)都会触发一个事件。

这在本质上比Winforms的绘画要高得多。看,画一个GUI是很昂贵的。如果每个用户触发的事件只执行一次,您将永远不会注意到这一点。但是,通过一个循环--包括每一个MS采样一个传感器--您就可以快速地霸占UI。实际上,我的第一次多线程测试似乎在很大程度上失败了,因为我发送的更新太多了,所以我简单地重载了GUI线程。从那以后,我知道不要越过进度栏。

您可以尽可能快地将数据添加到背景集合中,但不能快速绘制它们。老实说,画得比每秒30到60次(每17毫秒)更常见,反正也不会对任何人有什么帮助。通常您不能使用计时器,因为滴答可能会更频繁地发生,然后才能被处理--同样,带有溢出事件队列的GUI线程。

我没有任何WindowsForms的速率限制代码。但是,我想,在完成工作之后,在EventQueue结束时重新排队的事件是可行的。

票数 2
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60193157

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档