Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   FireMonkey (https://www.clubdelphi.com/foros/forumdisplay.php?f=50)
-   -   exception al llenar listview en anonymousthread (https://www.clubdelphi.com/foros/showthread.php?t=94776)

(MAJ) 10-07-2020 05:21:31

exception al llenar listview en anonymousthread
 
Buenas a todos. estoy teniendo un problema al un listview en un anonymousthread el thread en android(fmx) ejecuta una consulta rest, y el resultado lo quiero cargar en un listbox con un ciclo for, pero el listbox, despues de cargarlo me da una excepcion access violation, intente poner la creacion de los items en threadsynchronize, intente poner el for dentro del synchronize pero en todos me da un acessviolation, si alguien pudiera ayudarme le agradeceria


Código Delphi [-]
  

     for s in LDirs do

        tthread.Synchronize(nil,
          procedure
          var
          s:string;
          begin
            lboxDirectorio.BeginUpdate;
            lboxDirectorio.Items.Add(TPath.GetFileName(s) + CONST_X);
            lboxDirectorio.EndUpdate;
            application.ProcessMessages;
          end);
mas o menos ese es el codigo que utilizo para llenar el listview

bucanero 10-07-2020 10:38:26

hola a todos

en tu código veo varios cosas que te pueden dar erroes:
-pones el BeginUpdate / EndUpdate dentro del hilo y dentro del bucle, por lo que se repite en cada ciclo, cuando solo es necesario hacerlo una vez al principio y al final del proceso.
-Por otra parte, haces un application.ProcessMessages también dentro del hilo... si ya tienes un hilo secundario, el processMessages no es necesario, y de hacerlo hazlo en el hilo principal.

A mi este código me funciona bien:
Código Delphi [-]
procedure TForm2.ShowFiles(LDirs: TStringDynArray);
begin
    // Se pone el listBox en modo Update fuera del hilo
  lboxDirectorio.Items.BeginUpdate;
    // Se crea el hilo de proceso
  with TThread.CreateAnonymousThread(
    procedure
    var
      s: string;
    begin
        //...
      for s in LDirs do
        lboxDirectorio.Items.Add(TPath.GetFileName(s) + CONST_X);
        //...
    end) do begin
      //se marca para que termine de forma automatica
    freeOnTerminate := true;
      //se asigna el proceso que tiene que hacer cuando termine
    OnTerminate := ThreadTerminate;
      // se inicia el hilo
    start;
  end;
end;

procedure TForm2.ThreadTerminate(sender: TObject);
begin
  // al finalizaz el hilo se pone el listBox en modo normal
  lboxDirectorio.Items.EndUpdate;
  SetLength(Files, 0);
end;

procedure TForm2.Button1Click(Sender: TObject);
begin
  files := TDirectory.GetFiles('c:\a');
  ShowFiles(files);
end;

En este ejemplo en particular no utilizo tthread.Synchronize, a pesar de ser lo recomendable para actualizar un componente visual, pero en este ejemplo en particular solo escribe un único hilo de forma secuencial y no debe de dar problemas. En caso de usar varios hilos para actualizar el componente entonces si es ya necesario.

Neftali [Germán.Estévez] 13-07-2020 09:21:04

El Synchronize es obligatorio a utilizar en todos los Threads en el momento que acceder a un elemento que no sea "thread-safe", como son los componentes de la VCL.
Independientemente de si tú creas varios hilos o sólo uno, porque aunque tú sólo crees uno, hay otro que siempre está funcionando, que es el "Main thread" (el principal de la aplicación). Por lo tanto. debería utilizarse siempre.

Cita:

Empezado por bucanero (Mensaje 537931)
En este ejemplo en particular no utilizo tthread.Synchronize, a pesar de ser lo recomendable para actualizar un componente visual, pero en este ejemplo en particular solo escribe un único hilo de forma secuencial y no debe de dar problemas. En caso de usar varios hilos para actualizar el componente entonces si es ya necesario.


Neftali [Germán.Estévez] 13-07-2020 09:36:12

Cita:

Empezado por (MAJ) (Mensaje 537928)
...mas o menos ese es el codigo que utilizo para llenar el listview


Dos cosas:
  1. Yo haría una prueba sencilla para descartar, utilizando un thread "normal" (que no sea anónimo). Debería funcionar igual, pero para descartar algun problema con eso.
  2. Comentas en tu mensaje, que el código "...más o menos es este". Yo no lo veo problema a este mensaje, pero si tu código no es exactamente este, tal vez no estemos viendo lo que te está dando problemas.

(MAJ) 26-08-2020 21:50:24

Cita:

Empezado por Neftali [Germán.Estévez] (Mensaje 537947)
Dos cosas:
  1. Yo haría una prueba sencilla para descartar, utilizando un thread "normal" (que no sea anónimo). Debería funcionar igual, pero para descartar algun problema con eso.
  2. Comentas en tu mensaje, que el código "...más o menos es este". Yo no lo veo problema a este mensaje, pero si tu código no es exactamente este, tal vez no estemos viendo lo que te está dando problemas.

en un thread normal es lo mismo, y es "mas o menos", porque en el codigo que utilizo, tengo otras variables y procedimientos que no van al caso


La franja horaria es GMT +2. Ahora son las 12:42:49.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi