| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C++ Builder > Интерфейс пользователя & выполнение операции |
| Автор: Oberon83 17.11.2006, 14:44 |
| У меня есть операция работы с БД, которая занимает значительное время. Для того, чтобы пользователь не сидел "сложа руки" во время работы программы с БД я поместил операции работы с БД в отдельный поток. Но при выполнении потока кнопки формы не активны (т.е. активны, но ка-то странно). Дело в том, что пока поток не завершит свое выполнение обработчики событий для кнопок не обрабатываются (да и сами кнопки "не нажимаются", т.е. событие нажатия на кнопку фиксируется, но визуально это не отображается). В чем может быть дело? Может быть я неправильно понимаю саму идею потоков? Или все дело в методе Sinchronize потока (поток работает с визуалом формы)? Заранее благодарен за помощь. |
| Автор: RatHat 17.11.2006, 14:53 |
| А зачем такая возня с потоками? Либо периодически обновляй форму, либо проставь в цикле следующий код: Application->ProcessMessage(); Тогда программа будет время от времени обрабатывать накопившиеся сообщения. |
| Автор: Vyacheslav 17.11.2006, 15:14 | ||
| Наверное не правильно. Только не понятно в чем? Все должно быть не связано и работать так, как Вы и планировали. Иначе теряется thread Кстати о птичках. Надеюсь в нитке при работе с БД используются отдельные DataSet ? И возможно, коннекшион тоже. Есть вариант, что ваша нитка и нитка приложения вызывают используют какой-нибудь метод( нитка использует через Sinchronize), тогда идет попеременная блокировка ниток. Добавлено @ 15:16
Ему же не обновление кнопок нужно, а обеспечить нормальную работу пользователя, пока дополнительная нитка обрабатывает БД |
| Автор: anwe 17.11.2006, 15:20 |
| А созданый тобой поток "рабочий"? Может у тебя и в нем проводится общение с пользователем, в смысле обрабатываются сообщения? Надо, чтобы они обрабатывались в главном потоке, а рабочий лишь делал операции работы с БД. |
| Автор: Vyacheslav 17.11.2006, 16:23 | ||
С нетерпением ждем отчета |
| Автор: Oberon83 21.11.2006, 14:33 |
| Просмотрев код, систематизировал объекты, связанные с формой: 1. Используется конект к БД с помощью ТIBDataBase; 2. Используются запросы TIBQuery; 3. Так же идет работа с OleContainer (в нем открыта книга Excel в которую заносятся данные из БД); Теперь вопрос: как это все поместить отдельно в поток? Т.е. и подключение к БД, выполнение запросов и обработка объекта в контейнере ole? Т.к. блокировка кнопок форм скорее всего происходит потому что поток использует OlecOntainer для считывания/записи данных (поскольку при простом запуске функции потока пез метода Synchronize, компилятор быдает ошибку контейнера ole). P.S.: При работе потока, подключение к БД и запросы ничем больше не используются. |
| Автор: Vyacheslav 21.11.2006, 15:50 | ||
Во-первых, я ничего не понял Вам нужно, определить что может одновременно используется отвновным потоком и дополнительным потоком Вы же пишите
Ну и что следует из этого? Вы же используете некоторые методы через Synchronize. По всей видимости, либо эти же методы либо используемые объекты в них одновременно пользует основной поток Я не понял, что значит достаточно просто иметь отдельную копию для дополнительного потока. Как Вы уж это сделаете = Ваша проблема. Либо чденами класса Вашего TThread, либо используя средства дизайна - TDataModule со всеми необходимыми для работы дополнительного потока компонентами. |
| Автор: Oberon83 7.12.2006, 11:44 | ||
У меня примерно то же самое. На основной форме есть панель, которая закрывает основную рабочую область. На этой панели расположен прогрессбар и кнопка отмены, так вот она ведет себя так как я описывал в первом посте. Работу с БД (коннект, запросы) вынес в отдельный datamodule, но это все-равно не помогло. Скорее всего кнопка ведет себя так потому что я постоянно из потока работаю со прогрессбаром, с помощью которого показывается процесс выполнения операции. Как можно "вынести" обработку прогрессбара из потока? |
| Автор: Artemon 7.12.2006, 15:06 |
| А ты сначала попробуй отключить прогресс бар. Если все заработает на ура, вот тогда и выноси обработку прогресс бара из потока. |
| Автор: Oberon83 7.12.2006, 16:18 | ||||||||
| Похоже что без кода не обойтись. Структура программы выглядит следующим образом: у меня существуют статистические формы, которые приходят к нам в электронном виде. Их нужно занести в БД и потом производить какие-либо действия (например формирование сводных отчетов и т.д.). В БД, грубо говоря, существуют 3 таблицы: CATEGORY, THEMES, WRITE. CATEGORY - таблица, которая представляет из себя столбцы таблицы (наименование поля, номер ячейки Excel и т.д.), THEMES - строки (наименование поля, номер ячейки Excel), а WRITE - таблица для сохранения результатов (ном. столбца, ном. строки, значение). Excel формы загружаются в OLE контейнер, расположенный на форме. После этого мне нужно сохранить результат в базу, причем так, чтобы приложение "не висело" и пользователь мог остановить процесс загрузки данных как в OLE контейнер, так и в базу данных (как раз этого не получается).
Функция запуска потока:
Загрузка формы в программу:
Загрузка шаблона формы в OLE контейнер и начальная инициализация:
P.S.: Прошу не ругать за "удобочитаемость" кода. |