-
> [39] Kirill © (24.08.17 11:56)
> Это через команды Resume/Suspend?
Нет в 20, 21 и ещё далее информация.
-
Упс... Вот эти сообщения пропустил. Сейчас почитаю.
-
"Необходимо написать отправку данных в 1С в отдельном потоке. Программа должна делать выборку из БД данных, которые не отправлены и отправлять в 1С. В случае успешной отправки помечать запись как отправленную."
ConnectToDatabase;
while not Terminated and HasRecordsToSend do
begin
GetRecordToSend;
if not Terminated then
begin
SendRecord;
MarkRecordAsSent;
end;
end;
DisconnectFromDatabase;
Собственно все. И да, лучше в отдельном потоке, чтобы не мешать основному функционированию.
-
написать отдельное приложение, пущай по таймеру реплицирует енту бд в 1с, раз такие сложности. можно даж красиво в трей запихнуть, с анимацией.
-
Рискну внести небольшую добавку к коду Игоря.
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;
-
А здесь снова цикл...
Я наверно останусь с циклом, т.к. быстрое гугление информации с WaitForSingleObject привело к интересным статьям, но пока не изучил нормально. А текущий код осталось только доработать в плане создание нового подключения к БД и отдельной работы с ней и веб-сервиса.
Спасибо всем большое. А про WaitForSingleObject почитаю подробнее.
-
А еще лучше обернуть в try-except не только запись данных, а весь код Игоря, включая коннект к БД. Тогда в лог пропишется и сбой коннекта тоже.
> ТС
Вот этот код поместите в Execute. Метод HasRecordsToSend должен ждать либо таймаута (и тогда вернуть False), либо готовности данных для передачи (и тогда вернуть True).
-
> Метод HasRecordsToSend должен ждать либо таймаута
Метод должен определять, согласно условию, что в базе данных есть записи для отправки. Все.
-
> Игорь Шевченко © (24.08.17 14:21) [47]
И тогда получаем 100%-ную загрузку CPU бесполезным занятием.
А если HasRecordsToSend ждет (данных или тайм аута), то все получается вполне красиво.
1. В методе HasRecordsToSend используем WaiForSingleObject с подходящим объектом ядра.
2. Подготовив данные, главный поток взводит этот объект ядра. При этом второй поток просыпается, пересылает данные и ждет новой порции.
> ТС
Connect/Disconnect лучше тоже внести внутрь while - чтобы избежать ненужных коннектов, если данные еще не готовы.
-
> Connect/Disconnect лучше тоже внести внутрь while - чтобы
> избежать ненужных коннектов, если данные еще не готовы.
как же без конекта он узнает что пора посылать? )
-
> [48] Юрий Зотов © (24.08.17 15:04)
> А если HasRecordsToSend ждет (данных или тайм аута), то
> все получается вполне красиво.
Я выше предложил таймаут в главном (кассовом) потоке, чтобы второй (пересылающий) зря не пробуждался. Т.е. главный его пробудит при накоплении необходимого количества данных или через заданное время, если данных меньше минимального количества, или при завершении приложения.
ИШ, видимо, имел ввиду периодический запуск второго потока без дополнительного объекта синхронизации. Т.е. главный проверяет, не работает ли второй и, если не работает, то запускает его.
-
> [49] ухты © (24.08.17 15:10)
> как же без конекта он узнает что пора посылать?
Ну вот, приехали.
-
> [49] ухты © (24.08.17 15:10)
> как же без конекта он узнает что пора посылать?
Если объект ядра взведен (главным потоком) - значит, пора посылать.
-
Игорь, и Юрий, прошу прощения, но если закончатся записи на отправку цикл завершится.
Тогда в какой момент надо запускать этот поток? После записи чека в БД, чтобы он отправлялся?
-
> [53] Kirill © (24.08.17 16:06)
> Тогда в какой момент надо запускать этот поток?
Ты через один пост читаешь?
-
> Ты через один пост читаешь?
Простите, еще раз... Обновляю. Вижу старые сообщения. Отправляю сообщения - уже куча новых.
-
> Юрий Зотов © (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.
-
Только не INFINITE (когда данные кончатся, будет зависание).
if WaitForSingleObject(EventHasDataToSend, число) = WAIT_TIMEOUT then
continue;
-
> Kirill © (24.08.17 16:16) [55]
> Обновляю. Вижу старые сообщения. Отправляю
> сообщения - уже куча новых.
Дык... Вы же сами этого хотели - жаловались, что не помогают, такие-сякие...
:o)
Ваши слова были услышаны - вот и накидали кучу паззлов. Теперь дело за Вами - сложить из них правильную картинку.
Теперь топик, пожалуй, действительно закрыт - все, что было нужно сказать, уже сказано.
Удачи.
-
> Ваши слова были услышаны - вот и накидали кучу паззлов
Огромное всем спасибо... Как раз вчера оставшуюся часть дня изучал WaitForSingleObject и пытался понять на какое событие повесить. Спасибо за примеры.