Конференция "Начинающим" » Помогите написать работу с потоком [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 и пытался понять на какое событие повесить. Спасибо за примеры.
 
Конференция "Начинающим" » Помогите написать работу с потоком [D7]
Есть новые Нет новых   [118666   +35][b:0][p:0.001]