FAQ:WinAPI VCPP:прервать длительный процесс вычисления
У меня в программе имеется процедура, которая производит очень много вычислений. Как сделать так, чтобы пользователь мог прервать процесс вычислений?
1) В общем случае решение такое: вычисления производятся в одном потоке (T1) процесса, а обработка команд пользователя - в другом (T2). Одним из потоков может являться и основной поток. Поток T2, получив команду пользователя, выставляет определённый флаг (переменную, событие), доступный также и потоку T1. Поток T1, проверив флаг в определённый момент, прекращает/приостанавливает/продолжает свою работу. Естественно, скорость реакции T1 зависит от характера вычислений. Самый приятный вариант - вычисления, выполняемые в цикле, который часто повторяется. Тогда в начале или в конце цикла поток T1 просто проверяет флаг и принимает решение.
2) Есть ещё "ленивое решение" (подойдёт для простеньких приложений): вычисления выполняются в основном потоке, и также в начале цикла проверяется флаг. А кроме того, перед проверкой флага выполняется такой код:
// выполнить N сообщений из очереди сообщений int imsg; MSG m; for (imsg = 0; imsg < N; imsg++) { // выборка,выполнение и удаление одного сообщения // из очереди сообщений всех окон данного потока if (::PeekMessage(&m, 0, 0, 0, PM_REMOVE)) { // транслирование виртуальных клавиш ::TranslateMessage(&m); // обработка сообщения ::DispatchMessage(&m); } }
То есть будут обрабатываться все сообщения, в частности нажатия кнопок. Правда с тормозами. Тормоза можно попробовать регулировать числом N.
Примечание:
В любом случае необходимо тщательно продумать вариант, когда пользователь попытается закрыть программу во время вычислений. Самое простое: в главном окне программы перехватить WM_CLOSE и разрешить закрытие программы, либо вывести предупреждение и продолжить работу.