Excessive use of pens c#

Asked

Viewed 91 times

3

Good morning friends,

I am developing an application that should draw 4 graphics (for now), to draw in the way intended need to redraw the graphics several times and update them. With excessive use of the pen ("drawline") the performance falls a lot. When I stop drawing, my entire app runs normal, but when it starts drawing everything will be slow to lock completely (including the buttons). Please, does anyone know a way to optimize this code? Any tips? Thank you very much!! Below are the main parts of the code.

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    //metodo que chama o controle que desenha o gráfico---------------------------------------
    private void SerialCOM_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    {
        if (SerialCOM.IsOpen)
        {
            SerialPort sData = (SerialPort)sender;
            {
                string RxString = sData.ReadLine();
                bool result = int.TryParse(RxString, out int data);
                if (result)
                {
                    var atualdata = 5.0f * data / 1023.0f;

                    //CHAMADA DO CONTROLE
                    graphControl1.AddValue(atualdata, atualdata, atualdata, atualdata);

                    if (controlegravar == 1 && aquisicaodata.Count <= 6000) aquisicaodata.Add(atualdata);
                }
            }
        }
    }
}
//CONTROLE------------------------------------------------------------------------

public class GraphControl : Control
{

    public void AddValue(float value1,float value2,float value3,float value4)
    {
        _values1.Add(value1);
        _values2.Add(value2);
        _values3.Add(value3);
        _values4.Add(value4);
        Invalidate();
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
        var wid = (float)Width / (float)_dataCount;
        var total = 5;

        //-----------------------------------------1--------------------------------------------------------------------

        var lastPoint1 = new PointF(0F, (float)(2*Height/5) * 0.5F);
        var lastPoint2 = new PointF(0F, (float)(Height / 2));
        var lastPoint3 = new PointF(0F, (float)(7 * Height / 10));
        var lastPoint4 = new PointF(0F, (float)(9 * Height / 10));
        PointF newPoint1 = new PointF();
        PointF newPoint2 = new PointF();
        PointF newPoint3 = new PointF();
        PointF newPoint4 = new PointF();

        var idInit = _values1.Count - _dataCount;

        if (idInit < 0)
            idInit = 0;

        for (int i = idInit, a = 0; i < _values1.Count; i++, a++)
        {
            var value = (float)(_values1[i]);
            var porcent = value / total;

            if (porcent > 1) porcent = 1 ;
            var hg = porcent * (2*Height/5);

            newPoint1.X = (a + 1) * wid;

            if (porcent >= 1) newPoint1.Y = 2*Height/5 - hg;
            else newPoint1.Y = 2*Height/5 - hg - 1;

            using (var p = new Pen(Color.Lime, 0.1f)) e.Graphics.DrawLine(p, lastPoint1, newPoint1);

            lastPoint1 = newPoint1;

            //------------------------------------------------------------------------------------

            value = (float)(_values2[i]);
            porcent = value / total;

            hg = porcent * (Height / 5);

            newPoint2.X = (a + 1) * wid;

            newPoint2.Y = 3 * Height / 5 - hg;

            using (var p = new Pen(Color.Lime, 0.1f)) e.Graphics.DrawLine(p, lastPoint2, newPoint2);

            lastPoint2 = newPoint2;

            //------------------------------------------------------------------------------------

            value = (float)(_values3[i]);
            porcent = value / total;

            hg = porcent * (Height / 5);

            newPoint3.X = (a + 1) * wid;

            newPoint3.Y = 4 * Height / 5 - hg;

            using (var p = new Pen(Color.Lime, 0.1f)) e.Graphics.DrawLine(p, lastPoint3, newPoint3);

            lastPoint3 = newPoint3;

            //------------------------------------------------------------------------------------

            value = (float)(_values4[i]);
            porcent = value / total;

            hg = porcent * (Height / 5);

            newPoint4.X = (a + 1) * wid;

            newPoint4.Y = Height - hg;

            using (var p = new Pen(Color.Lime, 0.1f)) e.Graphics.DrawLine(p, lastPoint4, newPoint4);

            lastPoint4 = newPoint4;
        }

        base.OnPaint(e);
    }
}

Detail: the datareceived method is called by a timer with an interval of 3 ms. It needs to be very fast.

  • Felipe, Voce ta using what ? Web, Windows ?

  • The code is extended for a more accurate analysis. What you can do is decrease or delete all implicit and explicit code Cms. You will need to do a code debugging study and understand where the bottlenecks are. A tip where to start is here: https://docs.microsoft.com/en-us/visualstudio/profiling/? view=vs-2017 For the application to not lock while drawing, think about the possibility of working with Threads or Async/Await. We don’t have a complete sense of your tool to give an opinion, but it’s worth studying. About Threads: https://answall.com/questions/1490

  • There is no way to evaluate only with this piece of code without knowing the context as a whole... What is the interval in which onPaint is called?

  • Thiago, I’m using Windows.

  • Leandro, I’m going to edit here.

  • I’ll take a look at the links, thank you!!

Show 1 more comment

1 answer

1


A 3ms refresh rate is higher than the screen refresh rate either at 60fps (16.6ms) or 120fps (8ms). Even if you force Invalidate every 3 ms, it will not update at the same time. Try to optimize datareceived to work asyncronous and see the possibility of either increasing upgrade time or leaving the async Invalidate call.

  • good afternoon friend, I tried to use async await in the datareceived and the chart gets all warped. Could you give me tips on how I can leave the async invalidate call??

  • paid for the attention!

  • When I turn the Invalidate() async, the graph is drawn locking too, but the program starts running normally, the buttons do not lock.

  • 1

    I think it’s best not to call Invalidate every time the value is added because as you said, it’s very fast. try to make a logic to call Invalidate after the 10th Addvalue call or something. You’re forcing the chart to be drawn while it’s still drawing, so it hangs.

  • It worked, with 5 calls from Addvalue before Invalidate(), the program already cleared . Thanks guy!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.