Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 07-04-2014
juank1971 juank1971 is offline
Miembro
 
Registrado: feb 2008
Posts: 230
Poder: 17
juank1971 Va por buen camino
donde es mejor utilizar hilo

hola amigos:
En una aplicación se me esta demorando un poco el proceso de escaneo (extraer TXT) e inserción de ficheros, tengo un procedimiento que escanea una carpeta y va extrayendo todo el contenido txt y luego inserto los ficheros en una base de datos. necesito me recomienden como puedo implementra hilos de ejecucion en ese caso y en que lugar seria la mejor forma de hacerlo.

Código Delphi [-]
  //este es el procedimiento que recorre un árbol de directorios y me entrega los ficheros y muestra con progress 
procedure TForm2.RastreaDir(dir: string);
var
  FileSearch: TSearchRec;
  R: integer;
  s: string;
begin
  ChDir(dir);
  if FindFirst('*.*', FaDirectory, FileSearch) = 0 then
    repeat
      if ((FileSearch.Attr and FaDirectory) = FaDirectory) then
      begin
        application.ProcessMessages;
        if (FileSearch.Name <> '.') and (FileSearch.Name <> '..') then
          RastreaDir(dir + '\' + FileSearch.Name);
      end
      else
      begin
        application.ProcessMessages;
        if cancelando then Exit;
        PCarpeta.Progress := PCarpeta.Progress + 1;PCarpeta.Refresh;
        LFichero.Caption := FileSearch.Name; LFichero.Refresh;
        s := CaminoCompleto(dir + '\' + FileSearch.Name);
        if DataModule1.ExisteFichero(FileSearch.Name, s) then
        begin
          if smessagedlg('Organizador Electrónico',
            'El fichero ' + FileSearch.Name +
            ' existe en la base de datos desea sobreescribirlo ? ',
            mtInformation, [mbYes, mbno], 1) = mrYes then
            AgregaFichero(dir + '\' + FileSearch.Name);
        end
        else
           AgregaFichero(dir + '\' + FileSearch.Name);
      end;
      if cancelando then Exit;
    until FindNext(FileSearch) <> 0;
  FindClose(FileSearch);
end;

// y este es el de agregar los ficheros
procedure TForm2.AgregaFichero(n: string);
var
  File1: TFileStream;
  q: Tsqlquery;
  pag, s: string;
  idcarpeta, idfichero, idpadre: integer;
  PosS: integer;
  ins: boolean;
begin
  if not cancelando then
  begin
    Memo1.Lines.Clear;
    lEjecuta.Caption := 'Extrallendo texto...'; lEjecuta.Refresh;

    LFichero.Caption := 'Fichero: ' + ExtractFileName(n); LFichero.Refresh;

    LCarpeta.Caption := rightstr(ExtractFilePath(n), Length(ExtractFilePath(n)) - Length(CarpetaRaiz)); LCarpeta.Refresh;
    application.ProcessMessages;

    idcarpeta := InsertaCarpetas(n); //este procedimiento inserta en sqlite todas las carpetas en la estructura en que aparecen en  la base de datos

    if idcarpeta <> -1 then
    begin
      try
        ExtraeTexto(n, pag);
      except
        Memo1.Lines.Clear;
        pag:='1';
      end;

      InsertaFichero(n, idfichero);// este inserta el fichero en sqlite
      InsertaNombre(n, pag, idfichero, idcarpeta, '');//este inserta el nombre del fichero con el respectivo id_fichero e id_carpeta
    end;
  end;
  LiberarMemoria;// limpia memoria si se quedo algo en el proceso de sacar el texto de pdf etc.
end;

quisiera saber que sugerencia me dan y en que lugar se debiera implementar.

gracias juan
Responder Con Cita
  #2  
Antiguo 07-04-2014
Avatar de radenf
radenf radenf is offline
Miembro
 
Registrado: oct 2007
Ubicación: Viña del Mar,Chile
Posts: 608
Poder: 17
radenf Va por buen camino
Estimado juank1971:

No te diré donde es mejor utilizar utilizar hilos de ejecución, pero te contaré mi experiencia.
También tenía procesos que enlentecían mi programa y generaban unas esperas eternas y lo solucioné justamente utilizando los threads. Intenté crear los threads con el ThreadObject que trae Delphi y no logré jamás hacerlos funcionar (Yo soy menos que novato). Instalé los componentes TBMDThreadSet de Mitov, que son gratuitos y se pueden descargar de este link y me solucionaron todos los problemas.
Yo incluí los procesos que enlentecían la aplicación en el BMDThreadExecute y los llamo con BMDThread1.Start. Puedo asignarle acciones en los eventos Start, Terminate y Update y unir varios threads con el TBMDThreadGroup que incluyen estos componentes.
Te quiero señalar además que el uso de Application.ProcessMessages si bien permite la fluidez de algunos procesos, en mi caso la mayoría de las veces los hacían más lentos y luego de leer este artículo me decidí a eliminar la mayoría de ellos y dejar sólo los que consideré indispensables.
Espero haber sido de alguna ayuda.

Salu2
Responder Con Cita
  #3  
Antiguo 08-04-2014
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.269
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Los que comentas son típicos procesos para añadir dentro de Threads, puesto que a priori (si no he entendido mal) el programa no debe esperar a que estos acaben para continuar trabajando, sino que pueden "lanzarlos" en un segundo plano.
Yo dividiría en dos, por un lado en que extrae los TXT y por otro el que los inserta en Base de Datos (incluso podrían estar funcionando en paralelo -tipo producer/consumer-).

Ten en cuenta para el de base de datos que deberás crear conexiones especificas para el hilo (Base de Datos), no puedes compartir las del programa principal.

Por lo demás, si necesitas que seamos más concretos ya dirás.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #4  
Antiguo 09-04-2014
juank1971 juank1971 is offline
Miembro
 
Registrado: feb 2008
Posts: 230
Poder: 17
juank1971 Va por buen camino
ok, gracias por la ayuda, pero todavía tengo mis dudas es una estructura de árbol es la misma de windows llevándola a base de datos, pero el escaneo de los txt esta asociada un fichero, no veo como escanear texto sin esperar a que termine y me de el txt para insertarlo luego junto a lo demás, me explico mas:

Son la típica estructura de árbol que está en windows y voy a llevarla a base de datos sqlite.
\nueva carpeta\fichero.pdf
\nueva carpeta\otra carpeta\fichero1.pdf
\nueva carpeta\otra carpeta\fichero2.pdf.......

esta estructura en sqlite es las tablas :
carpetas (Id_carpeta ,id_padre,Nombre,Descripcion) //estructura de diretorios
ficheros (Id_fichero,fichero) // guarda el fichero como tal
nombres(Id_nombre,Nombre,Descripcion,Id_fichero,id_carpeta,Paginas,fecha)// guarda los nombres
contenido(id_fichero,contenidoTXT)// guarda el contenido txt del fichero en ese tabla con la facilidad (Full Text Shearch ) para hacer rapida las busquedas

entonces no logro ver los hilos independiente ya que en un mismo fichero todo el proceso , ahora estaba viendo lo de tdirectory que creo tengo todo en una lista y me parece que no tengo que hacer recursivo.
pero no se si sera exagerado crear un hilo para cada fichero o sea un hilo para "\nueva carpeta\otra carpeta\fichero1.pdf " y que el hilo se encarga de escanear el txt cuando lo tenga insertar de la base de datos.

otra cosa el proceso de insertar no lo veo tampoco muy separado al menos de un mismo fichero porque una tabla necesita el id devuelto para asociarlo con la otra como tampoco veo separado el de txt porque necesito el resultado del texto para insertarlo en las bases luego.

yo creo que ni yo mismo me entiendo.. ja.

voy a explorar con tdirectory a ver.
Responder Con Cita
  #5  
Antiguo 09-04-2014
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.269
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Estaba pensando que primero hacías una pasada por los ficheros para extraer el texto y guardarlo en un fichero (TXT) y luego en una segunda pasada cogías todos esos ficheros y los insertabas en Base de Datos.
Me da la impresión (por lo que entiendo ahora) que no lo haces así, sino que lo vas haciendo al mismo tiempo.

En ese caso hay 2 opciones:
(1) Separar y hacer 2 threads; Me parece más modular, pero se aleja de lo que tienes ahora y debes programar más.
(2) Hacer un único thread que haga lo que ahora; recorra ficheros, extraiga e inserte en Base de Datos. En este caso el thread es más complejo.

No hagas un thread por fichero. mucha complejidad y mucha sobrecarga.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Mejor Forma de Utilizar TZQuery JerS Conexión con bases de datos 7 27-02-2010 04:34:47
¿ Que es mejor utilizar sentencias o controles? emeritos Conexión con bases de datos 2 28-11-2006 00:57:28
La mejor forma de utilizar las horas en SQLServer Alexander Conexión con bases de datos 2 08-11-2006 15:07:17
En donde es mejor? Johnny Q OOP 7 12-07-2005 20:47:14


La franja horaria es GMT +2. Ahora son las 15:26:35.


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
Copyright 1996-2007 Club Delphi