bool bRunning = false; // глобальная переменная(работает поток или нет)
DWORD dwThId;
DWORD dwParam = 0;
.....
hThread = CreateThread(0, 0, Thread, &dwParam, 0, &dwThId); // где-то при нажатии кнопки
....
DWORD WINAPI Thread(LPVOID v)
{
bRunning = true;
..... //выполняем все что нужно
bRunning = false;
return 1;
}
Как сделать, чтобы прога не висла?
Значит есть прога. Я запускаю ей обработку, например, 20 гигов, и она это делает где-то минуту-две. В это время прога виснет, не разворачивается, если свернуть. Как сделать, чтобы она себя нормально вела?
Вероятно ты запускаешь свою функцию прямо в обработчике нажатия кнопки(или подобного) :-)))) Проще сделать так: по нажатии кнопки создается поток, вся работа выполняется в потоке. При этом интерфейс виснут не будет! :-))))
Чем мне не нравится работа с потоками, так это тем, что приходится везде ставить либо проверки на то, что поток выполняется уже или отключать часть кнопок перед потоком, а потом включать.
А куда деваться? Так или иначе приходится блокировать часть кнопок - чтобы юзеры не баловались. Можно написать простенькое РЕшоу и впихнуть ряд состояний. Еще метод (хоть и половинчатый) - на одну и ту же кнопку вешать 2 обратных функции... А TTimer запускается в своем потоке или использует тот же, что и остальные? Если в своем, то можно еще по нему как-то приостанавливать основной процесс. Или задробить данные на куски и обрабатывать по таймеру. Секундную задержку простить можно.. Нажал на кнопку, через секунду она сработала.
ох уж этот builder! :-)))) можно ведь без всяких TThread, одной строчкой поток создать...
2CDHAck 4.33: пробовал вставлять в обработчик, который тормозит, что-то вроде Application->ProcessMessages(); ? это чтобы система "отвлекалась" на другие процессы и события, обычно вставаляют в главный цикл перебора...
эффективная оказалась штука :) и вам советуб товарисч
Как-то писал прогу, что-то наподобии TotalCommander, и мне очень сильно помогли потоки...
Вы сами представьте, если бы "Explorer" был сделан на таймере, вы бы лазили по нему с задержкой 1 сек..... :) Я представляю как бесились бы пользователи.
Цитата: ШпиЁн
ох уж этот builder! :-)))) можно ведь без всяких TThread, одной строчкой поток создать...
Разве это сложно? :-))))
Разве это сложно? :-))))
Спасибо огромное! Там маленькая ошибочка есть - не объявлен хэндл потока, но это мелочь по сравнению с идеей. Все чуточку сложнее создания обычной функции c++, хотя вопрос спорный. Потоки самого Builderа (TThread) мне тоже кажутся слишком замороченными.
Мой код рабочий из программы (в основе предложенный вариант исправленный, немного измененный, дополненный комментариями и готовый к выполнению):
Код:
bool bRunning = false; // глобальная переменная (работает поток или нет) - можно не делать
DWORD dwThId; // идентификатор потока (без него нельзя в старых версиях Windows)
// DWORD dwParam = 0; // Если ничего передавать в поток не нужно, то переменная не нужна
// запустим все в потоке
DWORD WINAPI Thread(LPVOID v)
{
// делаем что нужно
bRunning = true; // поток работает (можно не делать)
int a = 1;
int b = 2;
int c;
c = a + b;
Form1->Memo1->Lines->Add("c = " + IntToStr(i+1)); // выведем в Memo формы 1 результат
ShowMessage("Готово"); // отобразим сообщение, что работа завершена
Form1->Button1->Enabled = true; //сделаем кнопку, запустившую поток актинвной
bRunning = false; // поток закончил работу (можно не делать)
// заканчисваем делать что нужно
return 1;
}
// отработчик нажатия кнопки
void __fastcall TForm1::Button1Click(TObject *Sender)
{
// запустим поток
// HANDLE hThread = CreateThread(0, 0, Thread, &dwParam, 0, &dwThId); // где-то при нажатии кнопки
//dwParam не используем, т.к. параметры не передаем в поток (NULL вместо него)
HANDLE hThread = CreateThread(0, 0, Thread, NULL, 0, &dwThId); // объявление выше было пропущено
CloseHandle(hThread); //закроем хэндл потока за ненадобностью
Button1->Enabled = false; // погасим кнопку, чтоб не запустить повторно
}
DWORD dwThId; // идентификатор потока (без него нельзя в старых версиях Windows)
// DWORD dwParam = 0; // Если ничего передавать в поток не нужно, то переменная не нужна
// запустим все в потоке
DWORD WINAPI Thread(LPVOID v)
{
// делаем что нужно
bRunning = true; // поток работает (можно не делать)
int a = 1;
int b = 2;
int c;
c = a + b;
Form1->Memo1->Lines->Add("c = " + IntToStr(i+1)); // выведем в Memo формы 1 результат
ShowMessage("Готово"); // отобразим сообщение, что работа завершена
Form1->Button1->Enabled = true; //сделаем кнопку, запустившую поток актинвной
bRunning = false; // поток закончил работу (можно не делать)
// заканчисваем делать что нужно
return 1;
}
// отработчик нажатия кнопки
void __fastcall TForm1::Button1Click(TObject *Sender)
{
// запустим поток
// HANDLE hThread = CreateThread(0, 0, Thread, &dwParam, 0, &dwThId); // где-то при нажатии кнопки
//dwParam не используем, т.к. параметры не передаем в поток (NULL вместо него)
HANDLE hThread = CreateThread(0, 0, Thread, NULL, 0, &dwThId); // объявление выше было пропущено
CloseHandle(hThread); //закроем хэндл потока за ненадобностью
Button1->Enabled = false; // погасим кнопку, чтоб не запустить повторно
}
Цитата: Andreyonka
Спасибо огромное! Там маленькая ошибочка есть - не объявлен хэндл процесса, но это мелочь по сравнению с идеей. Все чуточку сложнее создания обычной функции c++, хотя вопрос спорный. Потоки самого Builderа (TThread) мне тоже кажутся слишком замороченными.
Мой код рабочий из программы (в основе предложенный вариант исправленный, немного измененный, дополненный комментариями и готовый к выполнению):
Спасибо, братишка, наконец-то заработало!
Как хорошо, что хотя бы через 9.5 лет это кому-то помогло!