Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Cоздать поток 
:(
    Опции темы
Лена
Дата 11.10.2007, 12:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



Есть код перезапускающий службу и занимающий время.

Код

  TCursor Save_Cursor = Screen->Cursor;
   Screen->Cursor = crHourGlass;
                  S.Stop();
                  Application->ProcessMessages();
                  S.Start();
    Screen->Cursor = Save_Cursor;

Во время перезапука я хочу в отдельном потоке вывести доп.окно с компонентом Animate и индикатором на нем.
Опыта в этом маловато. Начинаю так:
Код

DWORD ThreadID;
 HANDLE hthread = CreateThread(
 0,
 0,
 ThreadFunc,
 0,
 0,
 &ThreadID);


Теперь функция потока:
Код

DWORD CALLBACK ThreadFunc(void * P)
 {
 / / тут отобразить  Form4->Show; //на форме Animate


 }


Как правильно оформить ThreadFunc? Чтобы во время перезапука службы отобразилось окно с Animate, а по окончании перезапука оно закрылось? 

Без потока индикатор у Animate замирает:
Код

Form4->Show();

                  Application->ProcessMessages();
                  TCursor Save_Cursor = Screen->Cursor;
                  Screen->Cursor = crHourGlass;
                  S.Stop();
                  Application->ProcessMessages();
                  S.Start();
                  Form4->Close();
                  Screen->Cursor = Save_Cursor;





Это сообщение отредактировал(а) Лена - 11.10.2007, 12:51
PM MAIL   Вверх
Lazin
Дата 11.10.2007, 13:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 18
Всего: 154



Через CreateThread лучше не делать, CRT его не инициализирует правильно (нельзя будет использовать ф-яя CRT). Можно либо взять TThread из VCL (в главном меню New->ThreadUnit, будет создан шаблон - куда можно писать свой код), либо делать это через _beginthread. Если чисто по логике, то лучше вынести в поток перезапуск службы, с формами и компонентами всё-же лучше работать из основного потока.
PM MAIL Skype GTalk   Вверх
Лена
Дата 11.10.2007, 13:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



Цитата(Lazin @  11.10.2007,  13:05 Найти цитируемый пост)
Если чисто по логике, то лучше вынести в поток перезапуск службы,


Тогда может так упростить?
Form4->Show();
ThreadFunc();


Код

DWORD CALLBACK ThreadFunc(void * P)
 {
 TCursor Save_Cursor = Screen->Cursor;
 Screen->Cursor = crHourGlass;
 S.Stop();
 S.Start();
 Screen->Cursor = Save_Cursor;
Form4->Close();
}



Это сообщение отредактировал(а) Лена - 11.10.2007, 13:37
PM MAIL   Вверх
Lazin
Дата 11.10.2007, 13:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 18
Всего: 154



Что-то вроде этого, только вместо вызова ф-ии нужно запустить поток. 
PM MAIL Skype GTalk   Вверх
Лена
Дата 11.10.2007, 13:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



Так?
Код

Form4->Show();
DWORD ThreadID;
 HANDLE hthread = CreateThread(
 0,
 0,
 ThreadFunc,
 0,
 0,
 &ThreadID);
}


Код

DWORD CALLBACK ThreadFunc(void * P)
 {
 TCursor Save_Cursor = Screen->Cursor;
 Screen->Cursor = crHourGlass;
 S.Stop();
 S.Start();
 Screen->Cursor = Save_Cursor;
Form4->Close();
}

PM MAIL   Вверх
dumb
Дата 11.10.2007, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 32
Всего: 158



Цитата(Лена @  11.10.2007,  14:22 Найти цитируемый пост)
Тогда может так упростить?
smile
и где тут отдельный поток? ты просто вынесла кусок кода в процедуру.

примерная схема действий:
File - New - Other... Thread Object, потом помещаешь свои S.Stop,S.Start в метод Execute.
ULenaThread.h
Код

class TLenaThread : public TThread
{
  public:
    __fastcall TLenaThread(bool susp);
    virtual void __fastcall Execute();
};

ULenaThread.cpp
Код

...
__fastcall TLenaThread::TLenaThread(bool susp) : TThread(susp) {}
//---------------------------------------------------------------------------
void __fastcall TLenaThread::Execute()
{
  Tblabla S;
  S.Stop();
  S.Start();
}


а в основном коде:
Код

Form4->Show();
TCursor Save_Cursor = Screen->Cursor;
Screen->Cursor = crHourGlass;
TLenaThread *thr = new TLenaThread(false);
while (!thr->Terminated())
  Application->ProcessMessages();
delete thr;
Screen->Cursor = Save_Cursor;
Form4->Close();


ps. покажи на всякий случай заголовочный файл от класса управляющего сервисом(S).
pss. кстати, тема пережевывалась уже раз сто - в поиске, думаю, все забито решениями этой проблемы... smile
PM MAIL   Вверх
Lazin
Дата 11.10.2007, 14:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 18
Всего: 154



Для создания потока в главном меню нужно выбрать File->New->Other
в появившемся окне выбрать Thread Object
потом появится окошко в котором нужно указать имя объекта (по которому к потоку можно обращаться в программе)
и имя потока (можно не указывать) в системе.
Builder создаст шаблон модуля
unit1.h
Код

//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
//---------------------------------------------------------------------------
class ServiceRestartThread : public TThread
{
private:
protected:
    void __fastcall Execute();
public:
    __fastcall ServiceRestartThread(bool CreateSuspended);
};
//---------------------------------------------------------------------------
#endif



unit1.cpp
Код

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------

//   Important: Methods and properties of objects in VCL can only be
//   used in a method called using Synchronize, for example:
//
//      Synchronize(&UpdateCaption);
//
//   where UpdateCaption could look like:
//
//      void __fastcall ServiceRestartThread::UpdateCaption()
//      {
//        Form1->Caption = "Updated in a thread";
//      }
//---------------------------------------------------------------------------

__fastcall ServiceRestartThread::ServiceRestartThread(bool CreateSuspended)
    : TThread(CreateSuspended)
{
}
//---------------------------------------------------------------------------
void __fastcall ServiceRestartThread::Execute()
{
    //---- Place thread code here ----
}
//---------
------------------------------------------------------------------
В метод Execute нужно добавить свой код
Код

void __fastcall ServiceRestartThread::Execute()
{
    S.Stop();
        S.Start();
}

В конструктор нужно добавить
FreeOnTerminate = true;
потом запускать поток
new ServiceRestartThread(false);
после того как поток закончит работу он будет удален автоматически.
PM MAIL Skype GTalk   Вверх
dumb
Дата 11.10.2007, 14:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 32
Всего: 158



Lazinsmile
Цитата(Lazin @  11.10.2007,  15:06 Найти цитируемый пост)
после того как поток закончит работу он будет удален автоматически.
а вот это, насколько я понял, Лене не нужно, так как ей надо "приостановить" программу на время работы потока и четко отловить его завершение...
PM MAIL   Вверх
Лена
Дата 11.10.2007, 14:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



dumb и Lazin, спасибо за помощь. Я пол года назад делала поток, блин за это время все забыла. smile 

Как все таки правльно проверить условие завершения? 

while (!thr->Terminated()) //?
[C++ Error] main.cpp(1701): E2109 Not an allowed type
PM MAIL   Вверх
dumb
Дата 11.10.2007, 14:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 32
Всего: 158



ой. это ж пропертя... while (!thr->Terminated)

PM MAIL   Вверх
Лена
Дата 11.10.2007, 14:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



Цитата(dumb @  11.10.2007,  14:26 Найти цитируемый пост)
ой. это ж пропертя... while (!thr->Terminated)


[C++ Error] main.cpp(1701): E2247 'TThread::Terminated' is not accessible

Все таки вроде должно быть while (!thr->Terminated()) , что ему не нравиться?
PM MAIL   Вверх
Лена
Дата 11.10.2007, 15:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



Может проверку надо как-то поставить в метод Execute() ?

PM MAIL   Вверх
dumb
Дата 11.10.2007, 16:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 32
Всего: 158



этот Terminated крайне ограниченным оказался... smile
Код

  while (WaitForSingleObject(reinterpret_cast<HANDLE>(t->Handle), 100)!=WAIT_OBJECT_0)
    Application->ProcessMessages();

PM MAIL   Вверх
Lazin
Дата 11.10.2007, 16:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 18
Всего: 154



Может использовать событие:

Код

создаем
HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);


в потоке
void __fastcall ServiceRestartThread::Execute()
{
***********
  SetEvent(hEvent); //говорим основному потоку что поток отработал
}

//запускаем поток
ServiceRestartThread * thr = new ServiceRestartThread(false);

while ( WaitForSingleObject(hEvent, 0) != WAIT_OBJECT_0 )
{
  Application->ProcessMessages();
}
delete thr;


Добавлено через 2 минуты и 44 секунды
Млин, не знал что есть свойство TThread::Handle, тогда так как dumb написал конечно лучше.
PM MAIL Skype GTalk   Вверх
Лена
Дата 11.10.2007, 16:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



Ух, спасибо вроде ожило. smile 

Я вот такой вариант пробовала:
bool potok=true; //глобальная
Код

void __fastcall SOSThread::Execute()
{
  S.Stop();
  S.Start();
  potok = false;
}


В коде:
Код

while(potok)
 Application->ProcessMessages();


Сначала показалось, что работает, а один раз выскочило исключение вызов чисто виртуальной функции. smile 

Сейчас почитаю, о параметрах WaitForSingleObject, а то не понятно. smile 

У меня служба не устнаовлена. Для проверки кода от dumb, я не много меняю метод:
Код

void __fastcall SOSThread::Execute()
{
  S.Stop();
  S.Start();
  Sleep(10000);
}


Вижу что мой Animate работает. Правильно ли я имитирую перезапукс службы?

Может для надежности сделать два потока? Один останавливает, другой запускает...

Это сообщение отредактировал(а) Лена - 11.10.2007, 16:30
PM MAIL   Вверх
dumb
Дата 11.10.2007, 16:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 32
Всего: 158



Цитата(Лена @  11.10.2007,  17:13 Найти цитируемый пост)
а один раз выскочило исключение вызов чисто виртуальной функции.
распространенная ошибка при неверной работе с потоками.
как это было: в Execute переменной potok присвоилось false и сразу после этого выполнение треда было приостановлено(менеджером потоков) и управление пришло в основной поток, там ты поймала изменение potok, вышла из цикла и грохнула объект. через какое-то время(это все в течение миллисекунд происходит, не подумай, что долго) управление вернулось в твой поток, происходит выход из метода Execute и далее(в TThread) должны происходить завершающие действия с объектом потока(выставление разных свойств, вызов метода OnTerminate, если назначен, итд). но объект уже удален. опаньки.

Цитата(Лена @  11.10.2007,  17:13 Найти цитируемый пост)
Правильно ли я имитирую перезапукс службы?
 smile довольно часто встречающееся явление - запукс службы  smile

Добавлено через 1 минуту и 41 секунду
Цитата(Лена @  11.10.2007,  17:13 Найти цитируемый пост)
Может для надежности сделать два потока? Один останавливает, другой запускает...
хм. а каким образом это может прибавить надежности? не надо. вот паузу между стоп, старт можно какую-нибудь небольшую(пару секунд) воткнуть.
PM MAIL   Вверх
Лена
Дата 11.10.2007, 16:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



Поставила службу. Обнаружилось не приятность, если строки:
 S.Stop();
 S.Start();
В методе Execute, то служба останавливается и не стратует.
А если эти строки поставить в основной код, то все нормально и останавливается и запускается.

Добавлено @ 16:42
Цитата(dumb @  11.10.2007,  16:36 Найти цитируемый пост)
вот паузу между стоп, старт можно какую-нибудь небольшую


Вот так?
void __fastcall SOSThread::Execute()
{
  S.Stop();
  Sleep(1000);
  S.Start();
}


Это сообщение отредактировал(а) Лена - 11.10.2007, 16:51
PM MAIL   Вверх
dumb
Дата 11.10.2007, 16:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 32
Всего: 158



Цитата(dumb @  11.10.2007,  14:52 Найти цитируемый пост)
ps. покажи на всякий случай заголовочный файл от класса управляющего сервисом(S).
реализация этого sos95gw полностью от вендора или таки "самописная"?

Цитата(Лена @  11.10.2007,  17:38 Найти цитируемый пост)
Вот так?
smile

PM MAIL   Вверх
Лена
Дата 11.10.2007, 16:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



Цитата(dumb @  11.10.2007,  16:49 Найти цитируемый пост)
полностью от вендора или таки "самописная"?


Не знаю.  smile 

После добавления sleep заработало.  smile 

PM MAIL   Вверх
dumb
Дата 11.10.2007, 17:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 32
Всего: 158



Цитата(Лена @  11.10.2007,  17:52 Найти цитируемый пост)
После добавления sleep заработало.
ну вот и славненько. можно со спокойной совестью громогласно объявить по экстренной связи "все на перекур нах!" smile

Цитата(Лена @  11.10.2007,  17:52 Найти цитируемый пост)
Не знаю.
если от вендора, то все ок. а если еще сами "наворачивали" оболочку, то надо убедиться, что там нет никаких обращений к формам итд(VCL).
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.1179 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.