1 (edited by Bullet3203 2017-12-11 08:53:46)

Topic: два и более таймеров

Возможно реализовать в проекте более двух таймеров? один например отвечает за отображения системного времени на форме, другой за оповещении о добавлении новой записи, третий за добавление новой записи в другой таблице? а то получается ошибка database is locked, ругается именно на процедуру OnTimer в которой и системное время и оповещение о добавлении записей

Re: два и более таймеров

Возможно. Нет ограничений на количество таймеров. Приложите пожалуйста ваш проект и описанием шагов приводящих к данной ошибке.

Dmitry.

Re: два и более таймеров

Вот имеется такой код таймера

procedure OnTimer;
var
    i: integer;
    w: integer;
    idNew: integer;
    idNew2: integer;
    sprinal, skomuvidano, sviddil, skto, skomu, spidroz: string;
    sMessage: string = '';
    sPopered: string = '';

    /////////////////////////////Отображение системного времени на формах///////////////////////////////////////
    begin
              Form1.Label48.Caption := FormatDateTime('c', Now);
              Aktirem.Label10.Caption := FormatDateTime('c', Now);
              aktrem_Andr.Label17.Caption := FormatDateTime('c', Now);
              aktrem_Kos.Label17.Caption := FormatDateTime('c', Now);
              aktrem_Gus.Label17.Caption := FormatDateTime('c', Now);
              aktrem_Vol.Label17.Caption := FormatDateTime('c', Now);
              Formzadanie.Label11.Caption := FormatDateTime('c', Now);
              ZapravkaKioc.Label10.Caption := FormatDateTime('c', Now);
              ZapravkaDSZN.Label10.Caption := FormatDateTime('c', Now);
              AktiExpertiza.Label4.Caption := FormatDateTime('c', Now);
              lampi.Label12.Caption := FormatDateTime('c', Now);
              rezim.Label20.Caption := FormatDateTime('c', Now);

    ///////////////////////////Вывод системного сообщения в указанное время///////////////////////////////////////
    begin
              sMessage := SQLExecute('SELECT message FROM reminder WHERE strftime(''%d.%m.%Y %H:%M:%S'', datetime) = strftime(''%d.%m.%Y %H:%M:%S'', ''now'', ''localtime'') ');
              if sMessage<>'' then
              begin
              ShowMessage(sMessage);
              end;
    end;

    //////////////////////////Вывод предупреждающего сообщения о закрытии программы///////////////////////////////
    begin
              sPopered := SQLExecute('SELECT w FROM popered');
              if sPopered <> '' then
              begin
              ShowMessage('УВАГА! Програма закриється для оновлення! Закрийте це повідомлення!');
              Glav.Close;
              end;
    end;

    /////////////////////////Проверка в таблице нового задания и оповещение пользователя о новом задании сообщением//////////////////////
    begin
              i := SQLExecute('SELECT count(*) FROM doshka');
              if ( i > prevCount) and (prevCount<>-1)  then
              begin
              idNew := SQLExecute('SELECT IFNULL(MAX(id),0) FROM doshka');
              if idNew<>0 then
              begin
              sprinal := SQLExecute('SELECT vidal FROM doshka WHERE id='+IntToStr(idNew));
              skomuvidano := SQLExecute('SELECT komuvidano FROM doshka WHERE id='+IntToStr(idNew));
              sviddil := SQLExecute ('SELECT skritkomuvidano FROM doshka WHERE id='+IntToStr(idNew));
              if (Glav.Label5.Caption = skomuvidano) and (Glav.Label10.Caption = sviddil) then
              begin
              ShowMessage('' + sprinal + ' видав(ла) Вам нове завдання! ');
              end;
              if (Glav.Label5.Caption <> skomuvidano) and (Glav.Label10.Caption = sviddil) then
              begin
              ShowMessage('' + sprinal + ' видав(ла) комусь або всім нове завдання! ');
              end;
    end;
              Formzadanie.TableGrid1.dbUpdate;
    end;
              prevCount := i;
end;

    ////////////////////////Проверка в таблице нового сообщения и оповещение пользователя о новом сообщении/////////////////////////////////
    begin
              w := SQLExecute('SELECT count(*) FROM chat');
              if ( w > prevCount2) and (prevCount2<>-1)  then
              begin
              idNew2 := SQLExecute('SELECT IFNULL(MAX(id),0) FROM chat');
              if idNew2<>0 then
              begin
              skto := SQLExecute('SELECT kto FROM chat WHERE id='+IntToStr(idNew2));
              skomu := SQLExecute('SELECT komu FROM chat WHERE id='+IntToStr(idNew2));
              spidroz := SQLExecute ('SELECT pidroz FROM chat WHERE id='+IntToStr(idNew2));
              if (Glav.Label5.Caption = skomu) and (Glav.Label10.Caption = spidroz) then
              begin
              ShowMessage('' + skto + ' написав(ла) Вам нове повідомлення! ');
              end;

    end;
              chat.TableGrid1.dbUpdate;
              modul.TableGrid1.dbUpdate;
    end;
              prevCount2 := w;
end;
end;

Вроде все работает, но периодически бывает вылетает ошибка database is locked! Когда нажимаешь на кнопку Debug в системном окошке ошибки, то программа показывает такие строчки:
1)

SQLExecute('SELECT message FROM reminder WHERE strftime(''%d.%m.%Y %H:%M:%S'', datetime) = strftime(''%d.%m.%Y %H:%M:%S'', ''now'', ''localtime'') ')

или
2)

 SQLExecute('SELECT w FROM popered')

или
3)

SQLExecute('SELECT count(*) FROM doshka')

или
4)

SQLExecute('SELECT count(*) FROM chat')

Получается что ругается только на то, что находится в процедуре OnTimer. Программа таким образом блочится на всех компьютерах, база сама лежит отдельно и к ней все подключаются по локальной сети.
Поэтому и возникло подозрение на то, что может из-за того, что все идет через один таймер и возникают такие ошибки...
Еще было замечено, что когда один компьютер, на котором запущена программа, уходит в спящий режим, то появляются те же ошибки и программа блочится либо у всех, либо только у того чей комп ушел в режим сна, или же только у нескольких пользователей...

Re: два и более таймеров

Пожалуйста прикладывайте проект. Тут например я не вижу какой интервал используется для таймера.

Dmitry.

Re: два и более таймеров

DriveSoft wrote:

Пожалуйста прикладывайте проект. Тут например я не вижу какой интервал используется для таймера.

Интервал указан такой

begin
     Timer := TTimer.Create (nil);
     Timer.OnTimer := @OnTimer;
     Timer.Interval := 1000;
     Timer.Enabled := True;
     end;

Проект вышлю на почту

Re: два и более таймеров

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


Откажитесь от таймеров либо переходите на использование клиент серверной базы данных MySQL.

Dmitry.

Re: два и более таймеров

DriveSoft wrote:

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


Откажитесь от таймеров либо переходите на использование клиент серверной базы данных MySQL.

Понятно, спасибо