Ir al contenido


Foto

Consulta en un hilo


  • Por favor identifícate para responder
8 respuestas en este tema

#1 el-mono

el-mono

    Advanced Member

  • Miembros
  • PipPipPip
  • 148 mensajes

Escrito 03 marzo 2017 - 02:59

Buenas tardes gente linda.

 

Tengo un método que recibe por parámetro una consulta SQL, ejecuto la consulta, trae los datos y formateo un Stringgrid para mostrar el resultado. 

Lo que quería hacer es meter en un hilo para evitar que se congele la interfaz grafica cuando los datos a traer son bastante, lo que dejo a continuación me trae los datos la primera vez que lo llamo pero cuando edito algún registro y llamo nuevamente a este método me tira un error y se me cierra el sistema.

 

Obviamente algo estoy haciendo mal, pero mi escaso conocimiento sobre hilos no me deja encontrar el error, uso Delphi 10.1 Berlin, Firemonkey y firebird. 


delphi
  1. procedure Tfrm_Edicion.Carga(Consulta: String);
  2. begin
  3. TThread.CreateAnonymousThread(
  4. procedure
  5. begin
  6. // Lo pirmero - limpiamos la grilla
  7. grilla.Clear;
  8.  
  9. with dmdatos.qConsulta do
  10. begin
  11. close;
  12. sql.Clear;
  13. sql.add(Consulta);
  14. open;
  15. if not eof then
  16. begin
  17. grilla.BeginUpdate;
  18. TThread.Synchronize(TThread.CurrentThread,
  19. procedure
  20. var i: Integer;
  21. begin
  22. grilla.columncount := dmdatos.qConsulta.Fields.Count;
  23. grilla.RowCount := dmdatos.qConsulta.recordcount+1;
  24. FetchOptions.RowsetSize := grilla.RowCount;
  25. lblRegistros.Text := 'Registros: ' + inttostr(grilla.RowCount);
  26.  
  27. for I := 0 to fields.Count-1 do
  28. grilla.Cells[i,0] := Fields.Fields[i].FieldName;
  29.  
  30. First;
  31.  
  32. while not EOF do
  33. begin
  34. for i := 0 to (dmdatos.qConsulta.Fields.Count - 1) do
  35. grilla.Cells[i,RecNo] := FieldByName(dmdatos.qConsulta.Fields.Fields[i].FieldName).AsString;
  36. Next
  37. end;
  38. grilla.EndUpdate;
  39. end
  40. );
  41. end;
  42. wait('',False);
  43.  
  44. end;
  45. end).Start;
  46.  
  47. end;


  • 0

#2 el-mono

el-mono

    Advanced Member

  • Miembros
  • PipPipPip
  • 148 mensajes

Escrito 12 marzo 2017 - 09:18

Me auto-respondo, si alguien necesita ejecutar una consulta que trae muchos datos y paraliza la interfaz gráfica. Con mis pocos conocimientos del tema y revisando los siguiente enlaces:

 

Interesante articulo sobre hilos del señor Malcolm  Groves

 

http://www.malcolmgr...om/blog/?p=1678

 

Y un vídeo indispensable sobre hilos 

 

https://www.youtube....2&v=rZfux4by0po

 

 

 

 

Yo lo resolví así:


delphi
  1. procedure TForm7.Button1Click(Sender: TObject);
  2. var
  3. aTask: ITask;
  4.  
  5. begin
  6. Rwait.Visible := True;
  7.  
  8. aTask := TTask.Create(procedure
  9. var i: Integer;
  10. begin
  11. // sleep (5000);
  12. // Aqui realizamos la consulta
  13. if TTask.CurrentTask.Status = TTaskStatus.Canceled then
  14. exit;
  15. with qConsulta do
  16. begin
  17. close;
  18. sql.Clear;
  19. sql.add('Select * from pacientes');
  20. open;
  21. if not eof then
  22. begin
  23. grilla.BeginUpdate;
  24. begin
  25. grilla.columncount := qConsulta.Fields.Count;
  26. grilla.RowCount := qConsulta.recordcount+1;
  27. FetchOptions.RowsetSize := grilla.RowCount;
  28. label1.Text := 'Registros: ' + inttostr(grilla.RowCount);
  29.  
  30. for I := 0 to fields.Count-1 do
  31. grilla.Cells[i,0] := Fields.Fields[i].FieldName;
  32. First;
  33.  
  34. while not EOF do
  35. begin
  36. for i := 0 to (qConsulta.Fields.Count - 1) do
  37. grilla.Cells[i,RecNo] := FieldByName(qConsulta.Fields.Fields[i].FieldName).AsString;
  38. Next
  39. end;
  40.  
  41. end;
  42. //
  43. end;
  44. end;
  45. if tTask.CurrentTask.Status <> TTaskStatus.Canceled then
  46. begin
  47. TThread.Queue(nil,
  48. procedure
  49. begin
  50.  
  51. // grilla.EndUpdate;
  52. // ShowMessage ('Hello');
  53. grilla.EndUpdate;
  54. rwait.Visible := false;
  55. end);
  56. end;
  57. end);
  58. aTask.Start;
  59. end; 


  • 0

#3 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.419 mensajes
  • LocationRepública Dominicana

Escrito 12 marzo 2017 - 09:31

Vaya, me será de utilidad justamente ahora, intentaba hacerlo de la manera siguiente:

Tthread.synchronize(Tthread.currentThread,<procedimiento>);

Pero igual me frizaba la aplicación.
  • 0

#4 el-mono

el-mono

    Advanced Member

  • Miembros
  • PipPipPip
  • 148 mensajes

Escrito 12 marzo 2017 - 09:46

Mira el articulo de Groves donde aconseja utilizar en lugar de synchronize cambiar por TThread.Queue

 

En este otro articulo llego a la misma conclusión ademas de preguntar por el estado del hilo antes de continuar

 

http://robstechcorner.blogspot.com.ar/2015/02/tpl-ttask-example-in-how-not-to-use.html


  • 0

#5 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 831 mensajes
  • LocationArgentina

Escrito 12 marzo 2017 - 10:50

Cuidado con reutilizar la misma conexion para distintos hilos. Para ADO por ejemplo hay que crear una conexion dedicada por hilo


  • 0

#6 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.419 mensajes
  • LocationRepública Dominicana

Escrito 13 marzo 2017 - 04:44

Acabo de hacer la prueba con ése método, wow, que funciona de perlas.


  • 0

#7 el-mono

el-mono

    Advanced Member

  • Miembros
  • PipPipPip
  • 148 mensajes

Escrito 13 marzo 2017 - 05:19

Buenisimo Enecumene.

 

Agustin sabes que estoy probando todavía ese manera de trabajar y no me tira error y me trae los datos correctamente, lo pruebo en red también por las dudas. Pero si es posible me gustaría saber tu opinión al respecto.


  • 0

#8 moscomx

moscomx

    Newbie

  • Miembros
  • Pip
  • 6 mensajes

Escrito 16 agosto 2018 - 02:00

Hola, muy buena la información. ¿sera que tengan una versión equivalente para delphi 2007? ya que el código no funciona debido a que la clase(o interface) ITask no está disponible en Delphi 2007


  • 0

#9 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.419 mensajes
  • LocationRepública Dominicana

Escrito 17 agosto 2018 - 08:55

Hola, muy buena la información. ¿sera que tengan una versión equivalente para delphi 2007? ya que el código no funciona debido a que la clase(o interface) ITask no está disponible en Delphi 2007

 

Porque eso es parte de FMX no de VCL.


  • 0




IP.Board spam blocked by CleanTalk.