С Новым годом! Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
0 / 0 / 1
Регистрация: 07.08.2014
Сообщений: 63

Работа с графиком и большим количеством данных

20.09.2018, 15:51. Показов 1548. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день. Есть приложение для обработки приходящих в COM-порт данных и вывода их на экран. Данные приходят регулярно (около 70 значений в секунду), я их собираю в обработчике прерываний COM-порта и по таймеру каждую секунду отрисовываю на графике. Компонент для графиков - Steema TeeChart Lite.
Но возникла проблема - когда я в обработчике тиков таймера беру эти данные и отрисовываю, замедляется работа программы, вплоть до обработки данных COM-порта.
Выглядит это так: данные каждую секунду 100% должны быть в наличии, но во время отрисовки чуть ли не каждый второй тик таймера возникает момент, когда данных вообще нет. Из-за этого график становится рваным. Комментирую строку с отрисовкой - данные приходят и обрабатываются как по часам. Подскажите, пожалуйста, есть ли вариант выйти из этой ситуации? Или придется отрисовку заводить в отдельный поток? Или это тоже не поможет?

Вот код обработчика прерываний COM-порта:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private void ComPortDataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
            byte[] temp = new byte[7];
            lengthCom = 7;
            m_inLen = 0;
 
            try
            {
                string buf = comPort.ReadLine();
                if (buf.Length > 0)
                {
                        for (int i = 0; i < buf.Length; i++) // переписываем данные в буфер приема передачи
                            BuffIn[cnt,i] = (byte)buf[i];
                        cnt++;
                        b_dataRead = true;
                 }
            }
            catch
            { 
            }
}
Код кнопки "СТАРТ":
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
private void butStartStop_Click(object sender, EventArgs e)
{
                setKoefData();
                line1.Clear();
                line2.Clear();
                timeNow = System.DateTime.Now; // запомнить время
                timer1.Enabled = true;
                timer1.Start();
                // установить новый период для графика
                tChart1.Axes.Bottom.Minimum = 0;
                tChart1.Axes.Bottom.Maximum = 10000;
                tChart1.Update();
                comport.WriteStart();
}
А вот код обработчика событий таймера:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
private void timer1_Tick(object sender, EventArgs e)
{
            byte[,] tempBuf = new byte[1000, 6];
            int tempCnt = 0;
            int step = 0;
            //timer1.Stop(); // остановить таймер
            double del_x = ((TimeSpan)(DateTime.Now - timeNow)).TotalMilliseconds;
 
            if (comport.IsData)
            {
                Array.Copy(comport.BuffIn, tempBuf, comport.cnt * 6);
                tempCnt = comport.cnt;
                step = 1000 / tempCnt;
 
                float[] rez_data = new float[2];
                for (int i = 0; i < tempCnt; i++)
                {
                    pointGraf1 = (float)comport.DataToUInt32(i, tempBuf, 0);
                    pointGraf2 = (float)comport.DataToUInt32(i, tempBuf, 1);
 
                    rez_data[1] = (kod.Checked ? pointGraf2 : (koef * pointGraf2 / 1));
                    line2.Add(del_x, rez_data[1]);
                    del_x += step;
 
                    if (del_x >= (tChart1.Axes.Bottom.Maximum - 500))
                    {
                        tChart1.Axes.Bottom.Maximum += 500;
                        tChart1.Axes.Bottom.Minimum += 500;
                    }
                    tChart1.Update();
                    comport.ClearComPort();
                }
            }
            else
                MessageBox.Show("OOps...");
            comport.cnt = 0;
            //timer1.Start(); // вкл таймер
}
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
20.09.2018, 15:51
Ответы с готовыми решениями:

Работа с большим количеством данных
Есть форма добавления нового рабочего, примерно 40 полей... Передаются они постом. Первые 10 я описал ручками, ибо они обязательны и там...

Сделать ProgressBar при зависании формы (работа с большим количеством данных)
Здравствуйте, нужно сделать progress bar на исполнение кода. Суть в том, что иде работа с большими файлами и форма зависает при выполнении...

Работа с большим количеством кнопок
Здравствуйте! Столкнулся с проблемой: На форме много кнопок ,но код для события click практически одинаковый void __fastcall...

7
 Аватар для ViterAlex
8951 / 4863 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
20.09.2018, 16:45
Цитата Сообщение от Auratos Посмотреть сообщение
около 70 значений в секунду
т.е. примерно 14 мс. WinForms-таймер с такой точностью работать не будет. попробуй использовать этот.
Отрисовывать, конечно, с такой скоростью не будет, но оно и не нужно, достаточно отрисовки каждые 150 мс.
Приём данных и отрисовка должны выполняться разными потоками, может быть даже разными приложениями.
0
0 / 0 / 1
Регистрация: 07.08.2014
Сообщений: 63
20.09.2018, 18:42  [ТС]
Расскажите, пожалуйста, поподробнее про 150 мс. Просто это в данный момент 70 точек, чуть позже понадобится около 500 точек за секунду, если получится. И есть ли у вас хотя бы небольшой примерчик, как пользоваться таймером, на который вы дали ссылочку? ))
0
0 / 0 / 1
Регистрация: 07.08.2014
Сообщений: 63
21.09.2018, 13:54  [ТС]
Цитата Сообщение от ViterAlex Посмотреть сообщение
т.е. примерно 14 мс. WinForms-таймер с такой точностью работать не будет. попробуй использовать этот.
Отрисовывать, конечно, с такой скоростью не будет, но оно и не нужно, достаточно отрисовки каждые 150 мс.
Приём данных и отрисовка должны выполняться разными потоками, может быть даже разными приложениями.
И все-таки: почему работа с графическим компонентом тормозит даже работу с COM-портом?
0
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10425 / 5155 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
21.09.2018, 20:41
Auratos,
Во-первых, вы бы вынесли вот эти строки (30-31 в timer1_Tick):
C#
1
2
                    tChart1.Update();
                    comport.ClearComPort();
из тела цикла наружу. Что они делают внутри цикла?
Во-вторых, компонент chart скажем так, не очень быстрый. Для быстрой отрисовки можете использовать вот такой самописный график.
0
0 / 0 / 1
Регистрация: 07.08.2014
Сообщений: 63
21.09.2018, 21:09  [ТС]
Цитата Сообщение от Storm23 Посмотреть сообщение
Auratos,
Во-первых, вы бы вынесли вот эти строки (30-31 в timer1_Tick):
C#
1
2
                    tChart1.Update();
                    comport.ClearComPort();
из тела цикла наружу. Что они делают внутри цикла?
Во-вторых, компонент chart скажем так, не очень быстрый. Для быстрой отрисовки можете использовать вот такой самописный график.
Спасибо за наводку. В понедельник на работе попробую этот график использовать
0
0 / 0 / 1
Регистрация: 07.08.2014
Сообщений: 63
22.09.2018, 09:39  [ТС]
Цитата Сообщение от Storm23 Посмотреть сообщение
Auratos,
Во-первых, вы бы вынесли вот эти строки (30-31 в timer1_Tick):
C#
1
2
                    tChart1.Update();
                    comport.ClearComPort();
из тела цикла наружу. Что они делают внутри цикла?
Во-вторых, компонент chart скажем так, не очень быстрый. Для быстрой отрисовки можете использовать вот такой самописный график.
Я дома попробовал пример работы с графиком. Убрал оттуда автоматическое заполнение. Добавил нанесение точки по клику кнопки:
C#
1
2
list.Add(100.0f);
fastLineChart1.Invalidate();
Подскажите, пожалуйста, почему, во-первых, при запуске уже отрисована какая-то линия точек, во-вторых, при клике по кнопке самая первая точка добавляется в конец графика, а не в начало? Не пойму, где это поправить в коде:
C#
1
2
3
4
5
6
7
8
for (var x = 0; x < StepCount - 1; x++)
{
                var xx = XToPixels(x);
                if (xx < 0 || xx >= rect.Width) continue;
                var y1 = (float)Function(x);
                var y2 = (float)Function(x + 1);
                e.Graphics.DrawLine(pen, rect.Left + xx, rect.Bottom - YToPixels(y1), rect.Left + XToPixels(x + 1), rect.Bottom - YToPixels(y2));
}
0
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10425 / 5155 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
22.09.2018, 09:53
Цитата Сообщение от Auratos Посмотреть сообщение
Подскажите, пожалуйста, почему, во-первых, при запуске уже отрисована какая-то линия точек, во-вторых, при клике по кнопке самая первая точка добавляется в конец графика, а не в начало? Не пойму, где это поправить в коде:
Потому что это контрол предназначен для отображения графика типа FastLine. Это особый вид графиков, где по оси абцисс откладывается время. При этом, новые точки добавляются в конец графика, а предыдущие точки уезжают влево. Это позволяет отображать сигнал, где последние точки - всегда занимают крайне правую позицию, а предыдущие - всегда находятся левее. Смотрите например график курса валют.
Ну а прямая линия - потому что нужно же отображать сигнал который был ДО этого. А он был нулевой, вот и рисуется нулевая линия.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
22.09.2018, 09:53
Помогаю со студенческими работами здесь

Работа с большим количеством полей
Здравствуйте! Подскажите пожалуйста как можно упростить такую задачу: Есть форма для ввода данных (317 полей с именами 1,2,3...317)....

Работа с большим количеством pictureBox
Всем привет! Недавно начал изучать с# с windows forms, и вот возникла проблемка.. Есть поле из около 200 picture box, на которых будут...

Работа с большим количеством COM портов.
Доброго времени суток! Есть сервер под управлением Windows 2003, на наём установлены две платы раширения MOXA на 4 COM порта каждая + 2...

Работа с большим количеством строк в String
Доброго времени суток! Суть моей задачи : минимизировать градиентным методом функцию, для одномерной оптимизации использовать методы...

FileMapping. Работа с большим количеством страниц
Есть следующий код создания FileMapping: procedure TForm1.FormCreate(Sender: TObject); begin ffile:=CreateFile('ffile.txt',...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru