Мастера DELPHI, Delphi programming community Рейтинг@Mail.ru Титульная страница Поиск, карта сайта Написать письмо 
| Новости |
Новости сайта
Поиск |
Поиск по лучшим сайтам о Delphi
FAQ |
Огромная база часто задаваемых вопросов и, конечно же, ответы к ним ;)
Статьи |
Подборка статей на самые разные темы. Все о DELPHI
Книги |
Новинки книжного рынка
Новости VCL
Обзор свежих компонент со всего мира, по-русски!
|
| Форумы
Здесь вы можете задать свой вопрос и наверняка получите ответ
| ЧАТ |
Место для общения :)
Орешник |
Коллекция курьезных вопросов из форумов
KOL и MCK |
KOL и MCK - Компактные программы на Delphi
Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / rsdn.org

 
Чтобы не потерять эту дискуссию, сделайте закладку « предыдущая ветвь | форум | следующая ветвь »
Страницы: 1 2 3 4

Помогите написать работу с потоком [D7]


Inovet ©   (24.08.17 12:11[40]

> [39] Kirill ©   (24.08.17 11:56)
> Это через команды Resume/Suspend?

Нет в 20, 21 и ещё далее информация.


Kirill ©   (24.08.17 12:46[41]

Упс... Вот эти сообщения пропустил. Сейчас почитаю.


Игорь Шевченко ©   (24.08.17 12:57[42]

"Необходимо написать отправку данных в 1С в отдельном потоке. Программа должна делать выборку из БД данных, которые не отправлены и отправлять в 1С. В случае успешной отправки помечать запись как отправленную."


ConnectToDatabase;
while not Terminated and HasRecordsToSend do
begin
 GetRecordToSend;
 if not Terminated then
 begin
   SendRecord;
   MarkRecordAsSent;
 end;
end;
DisconnectFromDatabase;

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


KilkennyCat ©   (24.08.17 13:03[43]

написать отдельное приложение, пущай по таймеру реплицирует енту бд в 1с, раз такие сложности. можно даж красиво в трей запихнуть, с анимацией.


Юрий Зотов ©   (24.08.17 14:05[44]

Рискну внести небольшую добавку к коду Игоря.

ConnectToDatabase;
while not Terminated and HasRecordsToSend do
begin
 GetRecordToSend;
 if not Terminated then
 begin
   StartTransaction;
   try
     SendRecord;
     MarkRecordAsSent;
     CommitTransaction;
   except
     on E: Exception do
     begin
       RollbackTransaction;
       WriteErrorToLog(Now, E);
    end;
 end;
end;
DisconnectFromDatabase;


Kirill ©   (24.08.17 14:11[45]

А здесь снова цикл...

Я наверно останусь с циклом, т.к. быстрое гугление информации с WaitForSingleObject привело к интересным статьям, но пока не изучил нормально. А текущий код осталось только доработать в плане создание нового подключения к БД и отдельной работы с ней и веб-сервиса.
Спасибо всем большое. А про WaitForSingleObject почитаю подробнее.


Юрий Зотов ©   (24.08.17 14:15[46]

А еще лучше обернуть в try-except не только запись данных, а весь код Игоря, включая коннект к БД. Тогда в лог пропишется и сбой коннекта тоже.

> ТС

Вот этот код поместите в Execute. Метод HasRecordsToSend должен ждать либо таймаута (и тогда вернуть False), либо готовности данных для передачи (и тогда вернуть True).


Игорь Шевченко ©   (24.08.17 14:21[47]


> Метод HasRecordsToSend должен ждать либо таймаута


Метод должен определять, согласно условию, что в базе данных есть записи для отправки. Все.


Юрий Зотов ©   (24.08.17 15:04[48]

> Игорь Шевченко ©   (24.08.17 14:21) [47]

И тогда получаем 100%-ную загрузку CPU бесполезным занятием.

А если HasRecordsToSend ждет (данных или тайм аута), то все получается вполне красиво.

1. В методе HasRecordsToSend используем WaiForSingleObject с подходящим объектом ядра.

2. Подготовив данные, главный поток взводит этот объект ядра. При этом второй поток просыпается, пересылает данные и ждет новой порции.

> ТС

Connect/Disconnect лучше тоже внести внутрь while - чтобы избежать ненужных коннектов, если данные еще не готовы.


ухты ©   (24.08.17 15:10[49]


> Connect/Disconnect лучше тоже внести внутрь while - чтобы
> избежать ненужных коннектов, если данные еще не готовы.
как же без конекта он узнает что пора посылать? )


Inovet ©   (24.08.17 15:29[50]

> [48] Юрий Зотов ©   (24.08.17 15:04)
> А если HasRecordsToSend ждет (данных или тайм аута), то
> все получается вполне красиво.

Я выше предложил таймаут в главном (кассовом) потоке, чтобы второй (пересылающий) зря не пробуждался. Т.е. главный его пробудит при накоплении необходимого количества данных или через заданное время, если данных меньше минимального количества, или при завершении приложения.

ИШ, видимо, имел ввиду периодический запуск второго потока без дополнительного объекта синхронизации. Т.е. главный проверяет, не работает ли второй и, если не работает, то запускает его.


Inovet ©   (24.08.17 15:29[51]

> [49] ухты ©   (24.08.17 15:10)
> как же без конекта он узнает что пора посылать?

Ну вот, приехали.


Юрий Зотов ©   (24.08.17 15:37[52]

> [49] ухты ©   (24.08.17 15:10)

> как же без конекта он узнает что пора посылать?


Если объект ядра взведен (главным потоком) - значит, пора посылать.


Kirill ©   (24.08.17 16:06[53]

Игорь, и Юрий, прошу прощения, но если закончатся записи на отправку цикл завершится.
Тогда в какой момент надо запускать этот поток? После записи чека в БД, чтобы он отправлялся?


Inovet ©   (24.08.17 16:08[54]

> [53] Kirill ©   (24.08.17 16:06)
> Тогда в какой момент надо запускать этот поток?

Ты через один пост читаешь?


Kirill ©   (24.08.17 16:16[55]


> Ты через один пост читаешь?

Простите, еще раз... Обновляю. Вижу старые сообщения. Отправляю сообщения - уже куча новых.


Leonid Troyanovsky ©   (24.08.17 17:04[56]


> Юрий Зотов ©   (24.08.17 15:04) [48]

> 1. В методе HasRecordsToSend используем WaiForSingleObject
> с подходящим объектом ядра.

Подходящий объект это, видимо, CreateEvent.
Оный цикл д.б. не внутри HasRecordsToSend, а рядом с Terminated.

while not Terminated do
   begin
     WaitForSingleObject(EventHasDataToSend, INFINITE);
     GetRecordToSend;
     ..
     SendRecord;
     ..
   end;

T.е., если в первичном HasRecordsToSend, то он делает Set(Pulse)Event.

Ну, там еще Destroy дописать.

Так понятней, IMHO.

--
Regards, LVT.


Юрий Зотов ©   (24.08.17 19:48[57]

Только не INFINITE (когда данные кончатся, будет зависание).

if WaitForSingleObject(EventHasDataToSend, число) = WAIT_TIMEOUT then
 continue;


Юрий Зотов ©   (24.08.17 20:16[58]

> Kirill ©   (24.08.17 16:16) [55]

> Обновляю. Вижу старые сообщения. Отправляю
> сообщения - уже куча новых.


Дык... Вы же сами этого хотели - жаловались, что не помогают, такие-сякие...
:o)

Ваши слова были услышаны - вот и накидали кучу паззлов. Теперь дело за Вами - сложить из них правильную картинку.

Теперь топик, пожалуй, действительно закрыт - все, что было нужно сказать, уже сказано.

Удачи.


Kirill ©   (25.08.17 09:02[59]


> Ваши слова были услышаны - вот и накидали кучу паззлов

Огромное всем спасибо... Как раз вчера оставшуюся часть дня изучал WaitForSingleObject и пытался понять на какое событие повесить. Спасибо за примеры.


Страницы: 1 2 3 4 версия для печати

Написать ответ

Ваше имя (регистрация  E-mail 







Разрешается использование тегов форматирования текста:
<b>жирный</b> <i>наклонный</i> <u>подчеркнутый</u>,
а для выделения текста программ, используйте <code> ... </code>
и не забывайте закрывать теги! </b></i></u></code> :)


Наверх

  Рейтинг@Mail.ru     Титульная страница Поиск, карта сайта Написать письмо