termsl
@termsl

Из-за чего происходят зависания приложения при использовании PictureBox?

Добрый день коллеги, имеется не понятная мне проблема при использовании в приложении PictureBox - через некоторое время приложение при получении фокуса безбожно висит, и кушает одно ядро процессора целиком, продолжительное время, при этом GUI висит, потом прорисовывается и отлипает.
Если оставить приложение на часок в свернутом состоянии, потом вызвать, можно не дождаться отзыва.
Постепенно ест оперативную память, по нескольку мегабайт в час, пробовал профилировать в JustTrace - ничего клинического, именно в данных самой программы не обнаружил.
Если отключить перерисовку PictureBox - остальной код работает отлично, ничего не залипает и не ест память.

Mon_Paint - обработчик PictureBox.Paint()
public class Timeline
    {
        public int Data_IN;
        public int Data_OUT;
    }

 public class SimpleSNMP
    {
        public UInt32 Last_Uptime;
        public UInt32 Last_Octets_IN;
        public UInt32 Last_Octets_OUT;
        public double Last_Speed_IN;
        public double Last_Speed_OUT;
        public string Last_IN_buffer = "";
        public string Last_OUT_buffer = "";
        public int PosDraw = 1;
        public int Counter = 0;
        public int Counter_Error = 0;
        public string Sys_Name = String.Empty;

        public SimpleSNMP()
        {
            Clear_Data();
        }
  }


private void Mon_Paint(object sender, PaintEventArgs e)
        {
            DRAW(e.Graphics);
        }
        public void DRAW(Graphics _graf)
        {
            Point top  = new Point();
            Point middle = new Point();
            Point bottom = new Point();
            int half_width = area_w / 2;
             
            while (osnmp.Line.Count > half_width)
            {
                osnmp.Line.RemoveAt(0);
            }

            int x=0;
            foreach (Timeline Curr in osnmp.Line)
            {
                top.X = x;
                top.Y = 0;
                middle.X = top.X;
                double W = (double)area_h/100*(double)Curr.Data_IN;
                if (W > area_h) W = area_h;
                middle.Y = (area_h-(int)(W));
                bottom.X = top.X;
                bottom.Y = area_h;
                _graf.DrawLine(Pen_Back, top, middle);
                _graf.DrawLine(Pen_IN, middle, bottom);
                top.X = x+1;
                top.Y = 0;
                middle.X = top.X;
                W = (double)area_h / 100 * (double)Curr.Data_OUT;
                if (W > area_h) W = area_h;
                middle.Y = area_h - (int)(W);
                bottom.X = top.X;
                bottom.Y = area_h;
                _graf.DrawLine(Pen_Back, top, middle);
                _graf.DrawLine(Pen_OUT, middle, bottom);
                x += 2; ;
            }
            x = 1;

            //Рисуем сетку
            PointF text_pos = new PointF();
            Font text_font = new Font("Arial", 6);
            SolidBrush text_brush = new SolidBrush(Color.Black);
            SolidBrush back_brush = new SolidBrush(Color.White);
            float ypos = 0;
            for (int dec = 0; dec < 11; dec++)
            {
                ypos = (float)area_h - ((float)area_h/ 10 * dec);
                top.X = 0;
                top.Y =(int) ypos;
                bottom.X = area_w;
                bottom.Y = top.Y;
                _graf.DrawLine(Pen_Grid, top, bottom);
                text_pos.X=1;
                text_pos.Y=ypos+1;
                _graf.DrawString((dec * 10).ToString(), text_font, back_brush, text_pos);
                text_pos.X = 0;
                text_pos.Y = ypos;
                _graf.DrawString((dec * 10).ToString(), text_font, text_brush, text_pos);
            }
           // top = null;
           // text_pos = null;
           // middle = null;
           // bottom = null;

            text_font = null;
            text_brush = null;
            back_brush = null;

        }
  • Вопрос задан
  • 2874 просмотра
Решения вопроса 1
termsl
@termsl Автор вопроса
foreach (Timeline Curr in osnmp.Line) - а вот тут не может увеличиться количество проходов?
В правильном направлении подтолкнули, скорее всего не тут, а в этом месте:
while (osnmp.Line.Count > half_width)
            {
                osnmp.Line.RemoveAt(0);
            }

Данные заталкиваются в буфер, который shrink'ится в момент перерисовки графика, что при первом отображении формы наверное занимает время и процессор, сейчас попробую поменять.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
GavriKos
@GavriKos
Паузите приложение, смотрите где сейчас крутится основной поток. Скорее всего просто длительная отрисовка.
Ответ написан
Комментировать
termsl
@termsl Автор вопроса
Если брать эмпирически, то отрисовка должна занимать всегда одинаковое время, так как длительность цикла = ширине PictureBox.
Вот только через продолжительное время работы приложения этот цикл увеличивается по времени...?
Ответ написан
termsl
@termsl Автор вопроса
Да, так оно и есть, спасибо)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы