** Tatiana |
Отправлено: 04.10.2005, 06:21 |
|
Не зарегистрирован
|
В программе две формы. В одной при нажатии кнопки пвтаюсь вызвать поток, использующий vcl, но при его выполнении зависает вся программа. Как сделать, чтобы этого не происходило?
CODE | void __fastcall TForm3::Button1Click(TObject *Sender)
{
TForm1 *F=new TForm1(Application);
F->Show();
}
//------------------------------------------------------------------------
void __fastcall TTr::Execute()
{
Synchronize(Exec);
}
//---------------------------------------------------------------------------
void __fastcall TTr::Exec()
{
form->upd();
}
//---------------------------------------------------------------------------
void TForm1::upd()
{
while(1)
Label1->Caption=Edit1->Text;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
TTr *t=new TTr(false);
t->FreeOnTerminate=true;
t->form=this;
}
//------------------------------------------------------------------
|
Отредактировано Gedeon — 04/10/2005, 07:43 |
|
Gedeon |
Отправлено: 04.10.2005, 07:46 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
Ну и чему Вы удивляетесь
всегда истинно, поэтому и происходит постоянная
QUOTE |
Label1->Caption=Edit1->Text; |
Вот поток постоянно и занят
|
|
GIZMO |
Отправлено: 04.10.2005, 09:43 |
|
Машинист паровоза
Группа: Участник
Сообщений: 174
|
QUOTE (Gedeon @ 04/10/2005, 07:46) | Ну и чему Вы удивляетесь
всегда истинно, поэтому и происходит постоянная
QUOTE |
Label1->Caption=Edit1->Text; |
Вот поток постоянно и занят |
Ну и что? Занят то вторичный поток, а висит программа (т.е. mainthread).
while(1) — это нормально в потоке...
Почему не работает?
- Не надо ставить цикл в TForm1::upd(). Почему надеюсь объяснять не надо.
CODE |
//---------------------------------------------------------------------------
class TForm1;
class MyThread : public TThread
{
private:
TLabel *pLabel;
protected:
void __fastcall Execute(void);
void __fastcall UpdateLabel(void);
public:
__fastcall MyThread(bool CreateSuspended, TLabel *ALabel);
};
//---------------------------------------------------------------------------
__fastcall MyThread::MyThread(bool CreateSuspended, TLabel *ALabel)
: TThread(CreateSuspended), pLabel(ALabel)
{
FreeOnTerminate = true;
}
//---------------------------------------------------------------------------
void __fastcall MyThread::Execute()
{
//---- Place thread code here ----
while(!Terminated/*1*/) //while(1)так тоже работает, но выйти нам как-то надо?
Synchronize(UpdateLabel);
}
//---------------------------------------------------------------------------
void __fastcall MyThread::UpdateLabel()
{
//TODO: Add your source code here
static int i;
if(pLabel)
pLabel->Caption = IntToStr(i++);
}
//use
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
mtd = new MyThread( false, Label1);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
mtd->Terminate();
}
//---------------------------------------------------------------------------
|
|
|
Gedeon |
Отправлено: 04.10.2005, 09:54 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
Ну вообще говоря да. Я неправильно написал то, что имел ввиду, а по поводу
QUOTE |
while(1) — это нормально в потоке... |
ИМХО не нормально нигде, т.к. если уж нужен бесконечный цикл, то лучше
читаемость кода упрощается.
|
|
** Tatiana |
Отправлено: 04.10.2005, 10:14 |
|
Не зарегистрирован
|
Да я нарочно этот бесконечный цикл поставила для теста потока |
|
** Tatiana |
Отправлено: 04.10.2005, 10:26 |
|
Не зарегистрирован
|
На самом деле в цикле будет добавление точек в Series TChart-а, но т.к. точек очень много, а тормозить прогу не хочется, решила сделать поток. Значения будут браться из ADOQuery на той же форме. Как это лучше организовать? |
|
Gedeon |
Отправлено: 04.10.2005, 11:03 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
Ну я надеюсь Вы поняли смысл разговора, добавлять точки надо не мотодом формы, а непосредственно работая с чартом из функции в потоке.
|
|
olegenty |
Отправлено: 04.10.2005, 11:20 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
я бы на PostMessage всё это сделал...
|
|
Konstantine |
Отправлено: 04.10.2005, 14:05 |
|
Мастер участка
Группа: Модератор
Сообщений: 545
|
а насколько долго?
весь прикол как раз в том — что Вы работаете с компонентой через Synchronize — т.е. опять-таки через основной поток...
прямо из дополнительного потока работать с компонентами тоже нельзя — в лучшем случае будет очень долго обрабатываться, в худшем — вываливаться...
сделать лучше всего так (как предложил olegenty):
for
{//тело Вашего цикла
...
Application->ProcessMessages(); // вот это и будет делать обработку сообщений, в т.ч. и прорисовку окна и обработку кнопок
}
|
|
Gedeon |
Отправлено: 04.10.2005, 15:24 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
имеется ввиду напрямую с компонентом через synchronize а не напрямик из потока, если через метод формы то Application->ProcessMessages(); поможет, но я бы так не делал. olegenty предлагает сделать несколько иначе т.е. из потока PostMessage, а в форме эти сообщения ловить и рисовать, но я бы тоже пожалуй не стал возиться с мэссэджами ради этого.
|
|
olegenty |
Отправлено: 04.10.2005, 16:36 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
ну это смотря как задача стоит. если мессаг мало — почему бы и нет. если много — можно сделать и мало, наладив "фильтрацию" "радиосигнала". например — мессага всего одна: CM_MOTHERFUCKING_MESSAGE, LParam — флаг, определяющий, что являет собой WParam, WParam — инфа. и какие тогда проблемы? работай — нехочу...
|
|
Konstantine |
Отправлено: 05.10.2005, 11:37 |
|
Мастер участка
Группа: Модератор
Сообщений: 545
|
не, я так и не понял — зачем поток? сделать в осн. программе, а чтоб не "висла" — в цикл включить PostMessages...
поток нужно использовать только там, где без него вообще нельзя
|
|
GIZMO |
Отправлено: 06.10.2005, 08:16 |
|
Машинист паровоза
Группа: Участник
Сообщений: 174
|
QUOTE (Konstantine @ 05/10/2005, 11:37) | не, я так и не понял — зачем поток? сделать в осн. программе,
|
... точек очень много, а тормозить прогу не хочется...
(С) Татьяна
QUOTE | а чтоб не "висла" — в цикл включить PostMessages... |
И как это будет выглядеть, можно взглянуть?
|
|
Konstantine |
Отправлено: 06.10.2005, 09:00 |
|
Мастер участка
Группа: Модератор
Сообщений: 545
|
оговорился — не PostMessages а ProcessMessages
если правильно расставить ProcessMessages, то торможения не будет (хоть и проц на 100% будет пахать)
пример я уже показывал — повторюсь:CODE | while(куча раз) // или for
{Application->ProcessMessages();
... Ваши вычисления и построение точки
}
| выполнение Application->ProcessMessages(); — это обработка входящих сообщений форме — прорисовка, обработка клавишь и мыши... т.е. в этом месте цикл приостанавливается, чтоб обработать "зависание". после обработки проц возвращается и продолжает цикл...
простейший пример:
на форме Button1 — для запуска цикла и CheckBox1 — для остановки...CODE | void __fastcall TForm1::Button1Click(TObject *)
{
while(!CheckBox1->Checked)
{Application->ProcessMessages();
}
} |
Отредактировано Konstantine — 06/10/2005, 10:38
|
|