На нашем сайте мы используем cookie для сбора информации технического характера и обрабатываем IP-адрес вашего местоположения. Продолжая использовать этот сайт, вы даете согласие на использование файлов cookies. Здесь вы можете узнать, как мы пользуемся файлами cookies.
Я согласен
логотип upread.ru

Пример работы с BackgroundWorker C++ и заставляем работать Refresh


Потоки – одна из самых популярных тем в программировании. На самом деле в них ничего особо сложного нет, разобравшись с реализацией на одном языке программирования высокого уровня, вы уже и в другом сможете реализовать поток. Но есть несколько но. В этой заметке мы поговорим о реализации потоков с помощью встроенного элемента Visual studio C++ - это BackgroundWorker, а также при обход проблемы прорисовки и работы с элементами GUI.

Итак, попробуем на примере конкретной задачи разобраться потоками и отрисовкой их в визуал студио C++. Предположим, что на форме у нас есть pictureBox, на котором мы что-то рисуем. И нам требуется обновлять это что-то с частотой раз в полсекунды. Оператор Sleep(500) прекрасно справится с этой задачей, но до конца процесса визуализации мы увы, ничего не сможем сделать с нашей формой. Это некритично, если не требуется ставить паузу и процесс занимает немного времени. А нам нужна именно пауза.

В одной своей работе мне потребовалось сделать реализацию алгоритма сортировки Шелла с визуализацией оной. Алгоритм легко программируется на C++, визуализацию тоже, не мудрствуя лукаво, я сделал с помощью прямоугольников, высота которых была пропорционально чисел в массиве.



Теперь надо, собственно говоря, и поработать с потоками. Кидаем на форму элемент backgroundWorker1, а когда требуется его запустить, вызываем метод:

backgroundWorker1->RunWorkerAsync();
В самом потоке что-то делаем:

private: System::Void backgroundWorker1_DoWork(System::Object^  sender, System::ComponentModel::DoWorkEventArgs^  e) {
//что-то делаем, вычисляем и тд.
		Sleep (5000);
	}
	
И никакого подвисания не будет – в данном потоке выполняется одно, а форма и элементы управления работают.

Но у нас же визуализация алгоритма – давайте попробуем встроить в наш поток метод принудительной перерисовки pictureBox:

pictureBox1->Refresh();
И что мы видим? А ничего. Метод не будет отрабатывать. Не будет не выбрасывания ошибки, ничего – простой дойдет до этой строчки и перестанет работать данный поток. Почему так? В двух словах: нельзя управлять элементами формы из другого потока без некоторых ухищрений. Надо сделать так. Создадим еще один метод:

System::Void RefFre() {
   pictureBox1->Refresh();
}
И вызовем его через Invoke:

pictureBox1->Invoke(gcnew Action(this, &Form1:: RefFre));
Если надо передать какую либо переменную, то делаем так

pictureBox1->Invoke(gcnew Action<int>(this, &Form1:: RefFre), 0);
Соответственно, входящие параметры функции тоже надо изменить.

Вот теперь у нас все отлично скомпилируется, а перерисовка будет происходить тогда, когда надо – в фоновом потоке и расчет тогда же. Для остановки данного потока поставьте флаг WorkerSupportsCancellation true, а в нужном месте:

if (backgroundWorker1->CancellationPending) {
//прерываем, например…
break;
}
Вызов прерывания:

backgroundWorker1->CancelAsync();
Как видите, ничего особо сложного нет, но незнающий таких тонкостей человек может потратить немало времени для решения такой простой задачи. Если у вас что-то не получается, то вы можете написать мне. Не бесплатно, но недорого я помогу вам.

Кстати, напоминаю, что могу сделать для вас курсовые, лабораторные, практические и дипломные работы на C++, Java, C#, PHP. Так как я занимаюсь данной деятельностью не первый год, помогаю студентам, то у меня накопилась и продолжает копиться база решений (программ) по самым разным тематикам: от администрирования баз данных и до высшей математики. Так что заказывая программу для курсовой по программированию у меня, вы можете рассчитывать на самые низкие цены, если подобное я уже делал.




тегизаметки, си плюс плюс, visual studio, потоки, BackgroundWorker





Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.




7 шахматных стратегий
Окно на сайт, всплывающее через некоторое время


© upread.ru 2013-2019
При перепечатке активная ссылка на сайт обязательна.
Задать вопрос
письмо
Здравствуйте! Вы можете задать мне любой вопрос. Если не получается отправить сообщение через эту форму, то пишите на почу up777up@yandex.ru
Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.