Я пытаюсь повторить итерацию TClientDataSet и обновить TLabel и TProgressBar в Android, но получаю эту ошибку. Как я могу это исправить?
Это процедура выполнения. это первый раз, когда я работаю с многопоточностью в 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;
У вас будет больше шансов получить помощь, если вы предоставите код, вызывающий эту ошибку.
используя здесь хрустальный шар, вы пытаетесь обновить графический интерфейс из потока, который не является основным (GUI) потоком ...
Я написал код. Надеюсь, ты сможешь мне помочь. Спасибо
Хорошо, теперь, когда мы видим некоторый код, я вижу, что вы открываете соединение в отдельном потоке, а затем обновляете набор данных в основном потоке, что не сработает. Выполняйте всю тяжелую работу в своем отдельном потоке и отправляйте уведомления в основной поток о прогрессе ...
Также не трогайте компоненты графического интерфейса (например, индикатор выполнения) в отдельном потоке ...
Увидев, что вы новичок в многопоточности, начните с чтения документация и различных ресурсов в Интернете ...
@whosrdaddy ну, вы можете потрогать их, но доступ к ним должен быть синхронизирован с основным потоком пользовательского интерфейса
@FelixHernandez, укажите, в какой строке кода возникает ошибка. Отладчик должен вам это сказать.
@RemyLebeau: да, конечно, но было бы лучше, если бы поток был независимым от графического интерфейса, подход SOLID, кажется, неизвестен многим новым разработчикам ...
@RemyLebeau, как мне синхронизироваться с основным потоком пользовательского интерфейса?
@whosrdaddy Как я могу открыть соединение и делать обновления из основного потока?
@FelixHernandez посмотрите на TThread.Synchronize() и TThread.Queue(). Даже что-то, казалось бы, невинное, например чтение свойств пользовательского интерфейса, например ProgressBar.Min/Max, необходимо синхронизировать с потоком пользовательского интерфейса.
@FelixHernandez: увидев ваши вопросы, вы явно не читали мануал ... вот пример как это делать (сайт на итальянском, используйте гугл переводчик)
Один из подходов для обновления индикатора выполнения в основном потоке из дочернего потока:
Это предотвращает слишком частое обновление индикатора выполнения и позволяет потоку очень быстро обновлять прогресс.
Добро пожаловать в StackOverflow. Посетите центр помощи, особенно Как мне задать хороший вопрос?. Предоставьте минимальный воспроизводимый пример, показывающий, что ваш код дает сбой. И при чем тут многопоточность? Ваше описание не соответствует вашему заголовку.