Многопоточность в Delphi FMX

Я пытаюсь повторить итерацию TClientDataSet и обновить TLabel и TProgressBar в Android, но получаю эту ошибку. Как я могу это исправить?

Многопоточность в Delphi FMX

Это процедура выполнения. это первый раз, когда я работаю с многопоточностью в Delphi, и я хотел бы знать об этом.

Я надеюсь, что вы можете мне помочь.

procedure TThreadCatalogos.Execute;
    var i : Integer;
        AppPath : string;
    begin
        AppPath := System.IOUtils.TPath.GetPublicPath;
       ProgressBar.Min := 0;

       for i := round(ProgressBar.Min) to round(ProgressBar.Max) do begin
           // check if Self(thread) is terminated, if so exit
           if Terminated then
              Exit;
           Position := i;

           {*******************************************}

            Conexion.Open;
            //CLIENTES
            dsClientes.Open;
            //mtClientes.EmptyDataSet;
            dsClientes.First;
            ProgressBar.Max := dsClientes.RecordCount;
            while not dsClientes.Eof do
            begin
              if not mtClientes.Locate('nombre',dsClientes.FieldByName('nombre').AsString,[]) then
              begin
                Synchronize(procedure()
                begin
                  mtClientes.Insert;
                  mtClientes.Fields[0].Value := dsClientes.FieldByName('cliente_id').Asinteger;
                  mtClientes.Fields[1].Value := dsClientes.FieldByName('nombre').AsString;
                  mtClientes.Fields[2].Value := dsClientes.FieldByName('tipo').AsString;
                  mtClientes.Post;
                  mtClientes.SaveToFile(System.IOUtils.TPath.combine(AppPath,'CLIENTES.bin'),sfBinary);
                  lbl.Text := 'Cliente '+floattostr(ProgressBar.Value)+' de '+floattostr(ProgressBar.Max);
                  ProgressBar.Value := ProgressBar.Value + 1;
                 end);
              dsClientes.Next;
            end;
            //mtClientes.SaveToFile(System.IOUtils.TPath.combine(AppPath,'CLIENTES.xml'),sfXML);
            mtClientes.First;

            end); Exit;

          end;
           {************************************************}

       end;
    end;

Добро пожаловать в StackOverflow. Посетите центр помощи, особенно Как мне задать хороший вопрос?. Предоставьте минимальный воспроизводимый пример, показывающий, что ваш код дает сбой. И при чем тут многопоточность? Ваше описание не соответствует вашему заголовку.

Remy Lebeau 09.01.2019 22:22

У вас будет больше шансов получить помощь, если вы предоставите код, вызывающий эту ошибку.

Rich 09.01.2019 22:39

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

whosrdaddy 09.01.2019 22:53

Я написал код. Надеюсь, ты сможешь мне помочь. Спасибо

Felix Hernandez 09.01.2019 23:25

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

whosrdaddy 09.01.2019 23:45

Также не трогайте компоненты графического интерфейса (например, индикатор выполнения) в отдельном потоке ...

whosrdaddy 09.01.2019 23:46

Увидев, что вы новичок в многопоточности, начните с чтения документация и различных ресурсов в Интернете ...

whosrdaddy 09.01.2019 23:48

@whosrdaddy ну, вы можете потрогать их, но доступ к ним должен быть синхронизирован с основным потоком пользовательского интерфейса

Remy Lebeau 09.01.2019 23:48

@FelixHernandez, укажите, в какой строке кода возникает ошибка. Отладчик должен вам это сказать.

Remy Lebeau 09.01.2019 23:49

@RemyLebeau: да, конечно, но было бы лучше, если бы поток был независимым от графического интерфейса, подход SOLID, кажется, неизвестен многим новым разработчикам ...

whosrdaddy 09.01.2019 23:51

@RemyLebeau, как мне синхронизироваться с основным потоком пользовательского интерфейса?

Felix Hernandez 10.01.2019 00:14

@whosrdaddy Как я могу открыть соединение и делать обновления из основного потока?

Felix Hernandez 10.01.2019 00:14

@FelixHernandez посмотрите на TThread.Synchronize() и TThread.Queue(). Даже что-то, казалось бы, невинное, например чтение свойств пользовательского интерфейса, например ProgressBar.Min/Max, необходимо синхронизировать с потоком пользовательского интерфейса.

Remy Lebeau 10.01.2019 00:55

@FelixHernandez: увидев ваши вопросы, вы явно не читали мануал ... вот пример как это делать (сайт на итальянском, используйте гугл переводчик)

whosrdaddy 10.01.2019 08:35
0
14
736
1

Ответы 1

Один из подходов для обновления индикатора выполнения в основном потоке из дочернего потока:

  1. Используйте атомарно обновляемую глобальную переменную, например 32-битное целое число, которое вы обновляете в дочернем потоке.
  2. Используйте в форме событие TTimer, которое обновляет индикатор выполнения на основе значений в глобальных переменных.

Это предотвращает слишком частое обновление индикатора выполнения и позволяет потоку очень быстро обновлять прогресс.

Другие вопросы по теме