Конференция "Начинающим" » СУБД в доп.потоке [D7, MySQL]
 
  • Danz1 (28.07.10 15:24) [0]
    у меня очень виснет программа изза этого кусочка
    помогите сделать запросы в дополнительном потоке
    правильно... чтобы программа не висла...
    вот что накидал я


    type
      TMyThread1 = class(TThread)
      private
        { Private declarations }
      protected
        procedure DoWork;
      end;

    var
    T1   : TMyThread1;
     lefttime: integer;

    implementation
    uses unit1,unit4,unit5, Unit6;
    {$R *.dfm}

    procedure TMyThread1.DoWork;
    var ok:boolean;
    begin
         try
    MySQLResult:=MySQLClient.Query('SELECT pkey.lefttime FROM pkey WHERE pkey.`key` =  \"' + pkey + '\"',True,OK);
    lefttime:=strtoint(MySQLResult.FieldValueByName('lefttime'));
    except
     on E:EAccessViolation do
      form1.close;
    end;
    end;

    procedure TDataModule3.Timer10Timer(Sender: TObject);
    var
     ok:boolean;
    begin
      if  (strtoint(mygroupid)<>6) and (strtoint(mygroupid)<>9) then
       begin

        T1 := TMyThread1.Create(False);

        T1.Execute;

         form1.sLabelFX5.Caption:=inttostr(lefttime);

           if lefttime < 300 then

           begin
              form1.sLabelFX5.kind.Color:=clred;
           end
            else
            begin
            form1.sLabelFX5.kind.Color:=$0033CC33;
             end;

           if lefttime <> 0 then

               begin
                 T1.Terminate;
                 lefttime:=lefttime-1;
                 MySQLClient.Query('UPDATE pkey SET lefttime = \"' + inttostr(lefttime) + '\" WHERE pkey.`key` = \"' + pkey + '\"', True, OK);
               end
                else
              begin
                 T1.Terminate;
                 DataModule3.Timer10.Enabled:=false;
                 form1.Close;
              end;

       end
        else
       begin
       T1.Terminate;
       DataModule3.Timer10.Enabled:=false;
       form1.sLabelFX5.kind.Color:=$d6c043;
       form1.sLabelFX5.Caption:='Unlimited';
       end;

    end;

  • DanzI (28.07.10 15:26) [1]
    я ошибся вместо T1.Execute; поставьте  T1.DoWork;
  • Anatoly Podgoretsky © (28.07.10 15:56) [2]
    > Danz1  (28.07.2010 15:24:00)  [0]

    А где Execute?
  • DanzI (28.07.10 16:34) [3]
    я пытался с ним но оно зацикливалось...если можете обьяните
  • И. Павел © (28.07.10 16:39) [4]
    Таймер выполняется в главном потоке, и T1.Execute, поэтому, поже выполнится в главном потоке.
    PS: кстати, совсем недавно была почти такая же тема.
  • DanzI (28.07.10 16:40) [5]
    если вместе с ним то было бы так

    type
     TMyThread1 = class(TThread)
     private
       { Private declarations }
     protected
       procedure DoWork;
       procedure Execute; override;
     end;

    var
    T1   : TMyThread1;
    lefttime: integer;

    implementation
    uses unit1,unit4,unit5, Unit6;
    {$R *.dfm}

    procedure TMyThread1.DoWork;
    var ok:boolean;
    begin
        try
    MySQLResult:=MySQLClient.Query('SELECT pkey.lefttime FROM pkey WHERE pkey.`key` =  \"' + pkey + '\"',True,OK);
    lefttime:=strtoint(MySQLResult.FieldValueByName('lefttime'));
    except
    on E:EAccessViolation do
     form1.close;
    end;
    end;

    procedure TMyThread1.Execute;
    begin
      while not Terminated do
        Synchronize(DoWork);
    end;

    procedure TDataModule3.Timer10Timer(Sender: TObject);
    var
    ok:boolean;
    begin
     if  (strtoint(mygroupid)<>6) and (strtoint(mygroupid)<>9) then
      begin

       T1 := TMyThread1.Create(False);

       T1.Execute;

        form1.sLabelFX5.Caption:=inttostr(lefttime);

          if lefttime < 300 then

          begin
             form1.sLabelFX5.kind.Color:=clred;
          end
           else
           begin
           form1.sLabelFX5.kind.Color:=$0033CC33;
            end;

          if lefttime <> 0 then

              begin
                T1.Terminate;
                lefttime:=lefttime-1;
                MySQLClient.Query('UPDATE pkey SET lefttime = \"' + inttostr(lefttime) + '\" WHERE pkey.`key` = \"' + pkey + '\"', True, OK);
              end
               else
             begin
                T1.Terminate;
                DataModule3.Timer10.Enabled:=false;
                form1.Close;
             end;

      end
       else
      begin
      T1.Terminate;
      DataModule3.Timer10.Enabled:=false;
      form1.sLabelFX5.kind.Color:=$d6c043;
      form1.sLabelFX5.Caption:='Unlimited';
      end;

    end;


  • DanzI (28.07.10 16:41) [6]
    можете объяснить как его сделать в доп потоке пожалусто
  • DanzI (28.07.10 16:42) [7]
    у меня таймер должен брать каждую сек время сколько осталось...
  • И. Павел © (28.07.10 16:47) [8]
    Можно попробовать так:
     while not Terminated do
     begin
       Synchronize(DoWork);
       sleep(1000);
     end;

    А можно посылать запросы асинхронно.
  • DanzI (28.07.10 16:48) [9]
    что значит асинхронно ?
  • И. Павел © (28.07.10 16:53) [10]
    > что значит асинхронно ?

    Неужели гугл за 1 мин. просмотрели, и он вам ничего не подсказал про асинхронный режим?
  • Anatoly Podgoretsky © (28.07.10 16:58) [11]
    > DanzI  (28.07.2010 16:40:05)  [5]

    Это по Архангельски, в этом случае поток лишний.
  • Anatoly Podgoretsky © (28.07.10 16:59) [12]
    > DanzI  (28.07.2010 16:41:06)  [6]

    Что его, не стыкуется с правилами русского языка.
  • DanzI (28.07.10 17:08) [13]
    тогда можете посоветовать как можно сделать так чтобы уменьшить нагрузку ?... тк приложение виснет а что самое обидное не все а только mainmenu посоветуйте как можно исправить это положение ?
  • DanzI (28.07.10 17:42) [14]
    Попытался сделать отдельно от таймера запуск которой получается от создания формы... но эффект оно просто зависло...
  • DanzI (28.07.10 17:59) [15]
    Уважаемые знатоки помогите решить проблему
  • Anatoly Podgoretsky © (28.07.10 19:17) [16]
    > DanzI  (28.07.2010 17:08:13)  [13]

    Если приложение виснет, то ни о какой нагрузки говорить не приходится,
    сначала заставь работать, вот тогда можно говорить и о нагружке
  • DanzI (28.07.10 19:36) [17]
    Сама программа работает на локал очень здорово просто  грузит у других очень  но только у тех кто вне города... и то... бываю исключения у моего знакомого  совсем из другого города работает а у его друга который сидит на том же провайдере что и он нет... проверял все что только можно но точно дело не в ОС... это 100% тк одинаковые ОС у некоторых пашет у некоторых нет...
    Кстати виснет как... зависает только меню... и все  просто становится не кликабельным, убираю этот кусок кода и все у всех нормально....

    но кодом я пользуюсь не совсем этим мне просто посоветовали для снятия нагрузки использовать мульти потоки .

    вот оригинальный разницы почти нету...

    procedure TDataModule3.Timer10Timer(Sender: TObject);
    var
     ok:boolean;
     lefttime:integer;
    begin
     if  (strtoint(mygroupid)<>6) and (strtoint(mygroupid)<>9) then
       begin

         MySQLResult:=MySQLClient.Query('SELECT pkey.lefttime FROM pkey WHERE pkey.`key` =  \"' + pkey + '\"',True,OK);

         lefttime:=strtoint(MySQLResult.FieldValueByName('lefttime'));
         form1.sLabelFX5.Caption:=inttostr(lefttime);

           if lefttime < 300 then

           begin
              form1.sLabelFX5.kind.Color:=clred;
           end
            else
            begin
            form1.sLabelFX5.kind.Color:=$0033CC33;
             end;

           if lefttime <> 0 then

               begin
                 lefttime:=lefttime-1;
                 MySQLClient.Query('UPDATE pkey SET lefttime = \"' + inttostr(lefttime) + '\" WHERE pkey.`key` = \"' + pkey + '\"', True, OK);
               end
                else
              begin
                 DataModule3.Timer10.Enabled:=false;
                 form1.Close;
              end;
       end
        else
       begin
       DataModule3.Timer10.Enabled:=false;
       form1.sLabelFX5.kind.Color:=$d6c043;
       form1.sLabelFX5.Caption:='Unlimited';
       end;
    end;


  • DanzI (29.07.10 00:34) [18]
    не подскажете как можно наладить ?
  • Плохиш © (29.07.10 01:34) [19]

    > procedure TDataModule3.Timer10Timer(Sender: TObject);
    >


    >              DataModule3.Timer10.Enabled:=false;
    >

    Тут не надо ничего налаживать, тут руки недокодеру отрывать надо.
  • DanzI (29.07.10 03:16) [20]
    а зачем цитировать выключение таймера ?... в программе так задумано... вместо помощи... проще сказать простейшее и выйти...
  • Anatoly Podgoretsky © (29.07.10 08:37) [21]
    > DanzI  (28.07.2010 19:36:17)  [17]

    Вообще то потоки увеличивают общею нагрузку.
  • DanzI (29.07.10 12:41) [22]
    скажите как тогда можно это исправить... я понял только 1 программа не совсем виснет то есть на себя ресурсов она почти не берет виснет в программе только меню
  • DanzI (29.07.10 13:09) [23]
    мне посоветовали Application.ProcessMessages(); говорят использовать его только в циклах... попробовал вроде получилось ) только я не совсем понял как его применять просто в цикле прописывать ? и все ?
  • DanzI (29.07.10 15:11) [24]
    это отменяется ... ( делал по правилам эффекта опять же 0...
  • DanzI (29.07.10 15:30) [25]
    Я решил вернутся у потокам и сделал вот так но виснет


    lefttime:integer = значения берутся... то есть они верные и они существуют

    Юнит 1

    type
      TMyThread1 = class(TThread)
      private
        { Private declarations }
      protected
        procedure DoWork;
        procedure Execute; override;
      end;

    var
     T1 : TMyThread1;

    implementation

    uses Unit3, Unit2,unit4, Unit5, unit8, Unit10;
    {$R *.dfm}

    procedure TMyThread1.Execute;
    begin
      while not Terminated do
       begin
        Synchronize(DoWork);
        sleep(1000);
       end;
    end;

    procedure TMyThread1.DoWork;
    var ok:boolean;
    begin
     try
       MySQLResult:=MySQLClient.Query('SELECT pkey.lefttime FROM pkey WHERE pkey.`key` = \"' + pkey + '\"',True,OK);
       lefttime:=strtoint(MySQLResult.FieldValueByName('lefttime' );
       lefttime:=lefttime-1;
       MySQLClient.Query('UPDATE pkey SET lefttime = \"' + inttostr(lefttime) + '\" WHERE pkey.`key` = \"' + pkey + '\"', True, OK);
    except
      on E:EAccessViolation do
        begin
         T1.Terminate;
         form1.close;
        end;
      end;
    end;

    procedure TForm1.FormCreate(Sender: TObject);
    ..........................
    ..........................
    if (strtoint(mygroupid)<>6) and (strtoint(mygroupid)<>9) then
     begin
     T1 := TMyThread1.Create(False);
     T1.Execute;
     end;
    end;

    Юнит 2

    procedure TDataModule3.Timer10Timer(Sender: TObject);
    var
     ok:boolean;
    begin
      if (strtoint(mygroupid)<>6) and (strtoint(mygroupid)<>9) then
       begin

         form1.sLabelFX5.Caption:=inttostr(lefttime);

           if lefttime < 300 then
              form1.sLabelFX5.kind.Color:=clred
            else
              form1.sLabelFX5.kind.Color:=$0033CC33;

           if lefttime <= 0 then
              begin
                 DataModule3.Timer10.Enabled:=false;
                 T1.Terminate;
                 form1.Close;
              end;
       end
        else
       begin
       DataModule3.Timer10.Enabled:=false;
       T1.Terminate;
       form1.sLabelFX5.kind.Color:=$d6c043;
       form1.sLabelFX5.Caption:='Unlimited';
       end;
    end;

  • Плохиш © (29.07.10 19:27) [26]

    > DanzI   (29.07.10 03:16) [20]
    >
    > а зачем цитировать выключение таймера ?... в программе так
    > задумано... вместо помощи... проще сказать простейшее и
    > выйти...

    Была процетирована строка сделанная недокодером, а что она делает совершенно не важно. Прочитай про переменную self.
    А искать проблемы в коде, сделанном без понимания основ, является бессмысленно выкинутым временем.
  • Плохиш © (29.07.10 19:29) [27]

    > procedure TMyThread1.Execute;
    > begin
    >   while not Terminated do
    >    begin
    >     Synchronize(DoWork);
    >     sleep(1000);
    >    end;
    > end;
    >

    Кто-нибуть может объяснить какой здесь великий смысл в потоке, всё всё-равно делается в основном потоке.
  • Игорь Шевченко © (29.07.10 20:59) [28]

    > Кто-нибуть может объяснить какой здесь великий смысл в потоке


    тебе не пофиг ?
  • Anatoly Podgoretsky © (29.07.10 23:01) [29]

    > всё всё-равно делается в основном потоке.

    Не все, спит то в дополнительном :-)
  • DanzI (30.07.10 00:30) [30]
    пытаюсь параллельно читать и говорят что в этом месте  T1.Execute; ставить нужно T1.Suspended := false;

    procedure TForm1.FormCreate(Sender: TObject);
    ..........................
    ..........................
    if (strtoint(mygroupid)<>6) and (strtoint(mygroupid)<>9) then
    begin
    T1 := TMyThread1.Create(False);
    T1.Suspended := false;
    end;
    end;

    И везде заменил T1.Terminate; на T1.Free; т.к выбивает ошибку


    > Была процетирована строка сделанная недокодером, а что она
    > делает совершенно не важно. Прочитай про переменную self.
    >
    > А искать проблемы в коде, сделанном без понимания основ,
    >  является бессмысленно выкинутым временем.


    Программа опять заработала .... но только у меня и у моих друзей с города...

    Прошу помогите переделать, пытаюсь найти Примеры с потоками но нашел только теми которыми пользуюсь сейчас... и информации внятной не так уж и много... Если вам не трудно объясните, не нужно говорить что человек не понимает итд итп вместо этого лучше посоветовать.
  • Плохиш © (30.07.10 00:58) [31]

    > и информации внятной не так уж и много...

    Дальше можно не продолжать, ибо мне пофиг.
  • turbouser © (30.07.10 01:05) [32]

    > Если вам не трудно объясните

    Не трудно.

    > вместо этого лучше посоветовать.

    Что посоветовать, когда автор сам не понимает что делает и не объясняет что делает? Мм?
  • Германн © (30.07.10 01:21) [33]

    > Если вам не трудно объясните, не нужно говорить что человек
    > не понимает итд итп вместо этого лучше посоветовать.

    В переводе на русский это выглядит так - "Дайте готовый код".
  • DanzI (30.07.10 02:30) [34]
    Ладно вообщем хороших программистов много... желающих помочь не так уж и много. Спасибо Anatoly Podgoretsky , И. Павел. всем остальным которые участвовали отдельное спасибо за *Теплое гостеприимство*,*Мудрые советы*,и не как не грубость.

    и к тому же

    > Дальше можно не продолжать, ибо мне пофиг.

    я не думаю что вы настолько мудрый человек чей совет был бы полезен вы толком ничем по этой теме не помогли, кроме как хамства и чрезвычайной гордостью.
  • Германн © (30.07.10 02:38) [35]

    >
    > я не думаю что вы настолько мудрый человек чей совет был
    > бы полезен

    Прежде чем "думать" надо "изучить". А вот этого у тебя и нет.
  • DanzI (30.07.10 02:47) [36]
    Обычно думают не только после обучения но и в процессе.
  • Anatoly Podgoretsky © (30.07.10 07:35) [37]
    > DanzI  (30.07.2010 00:30:30)  [30]

    Сначала букварь, потом помощь, иначе потеряные деньги.
 
Конференция "Начинающим" » СУБД в доп.потоке [D7, MySQL]
Есть новые Нет новых   [134434   +28][b:0][p:0.006]