Club Delphi  
    Paypal   FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Coloboración Paypal con ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 09-02-2011
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: 19.441
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
Cita:
Empezado por gluglu Ver Mensaje
Es el único problema que me puedo imaginar, si acaso. En el otro procedimiento al que se llama desde cada uno de los Threads que puedan estar activos concurrentemente, lo que hago es

Código Delphi [-]
Calculate_Total.Aux_Random := Aux_R1;
No me ha quedado claro dónde está colocada esta asignación.
¿Dónde se encuentra esta línea?
¿Dentro del thread?

AÑADO:
(1) No acabo de ver de dónde sale o dónde está definida la variable Pos_Array que utilizas para acceder al array.
(2) Sigo pensando que en lugar de llegar al formulario que está asociado al thread utilizando el array, sería más sencillo que pasaras el propio formulario como parámetro al thread.
__________________
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.

Última edición por Neftali [Germán.Estévez] fecha: 09-02-2011 a las 10:19:15.
Responder Con Cita
  #2  
Antiguo 09-02-2011
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: 19.441
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
Aquí tienes un ejemplo con estructura similar al tuyo; Faltan algunas cosas como la de la variable que te he comentado antes, pero hasta aquí, con lo que hemos comentado no da problemas.

UPDATE: Corregidos los adjuntos
Archivos Adjuntos
Tipo de Archivo: zip FormulariosYthreads.rar.zip (85,4 KB, 10 visitas)
Tipo de Archivo: zip FormulariosYthreads.zip (257,1 KB, 8 visitas)
__________________
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.

Última edición por Neftali [Germán.Estévez] fecha: 09-02-2011 a las 17:51:32.
Responder Con Cita
  #3  
Antiguo 09-02-2011
Avatar de gluglu
[gluglu] gluglu is offline
Miembro Premium
 
Registrado: sep 2004
Ubicación: Málaga - España
Posts: 1.455
Poder: 23
gluglu Va por buen camino
Hola Neftalí !

Antes de nada, decirte que el último ZIP añadido no está accesible en estos momentos. El contenido es ilegible y da error. Así que no he podido revisar este último código que adjuntas.

He estado revisando todo mi código y todos vuestros comentarios.

... y mira que hace algunos años ya que estuve revisando el ejemplo que pones en un mensaje más arriba.

Ya me queda claro que no declaré el Thread Calculate_Total en la unit List_General como private. Entiendo que en cualquier caso, también se podría declarar como público, no es verdad ?

También llevo muchos años siguiendo el foro y he denotado en todas mis consultas, que cada uno pasa parámetros de manera diferente a procedimientos. En el primer ejemplo tu utilizas el propio método Create para pasar los parámetros a cada Thread. Personalmente nunca lo he utilizado así y no sé si es mejor o peor (aunque a mi me funciona hasta el día de hoy perfectamente) el pasar los parámetros mediante variables públicas en el procedimiento llamado.

Por lo tanto entiendo también que puedo pasar tanto la referencia de la instancia del Form List_General en concreto que ejecuta el Thread al propio Thread, o puedo pasar una variable Pos_Array que es la cual me indica la posición en el Array Arr_List declarado en el MainForm, y después hacer referencia al listado en concreto como MainForm.Arr_List[Pos_Array] y a continuación el elemento que quiera.

En respuesta a tu pregunta de donde sale precisamente esa variable Pos_Array, cuando creo en el MainForm una nueva instancia de List_General lo que hago es añadir un elemento al Array Arr_List y su posición en el Array la asigno a la variable Pos_Array que a su vez se la paso a List_General para saber en cada form qué referencia es en concreto del MainForm.Arr_List

Además indico aquí que cuando hago un Free de una instancia de List_General, en MainForm.Arr_List busco la referencia en concreto y le asigno el valor Nil. Por lo tanto, respecto al párrafo anterior, al crear un nuevo List_General, no siempre lo añado al final, sino busco la primera posición en MainForm.Arr_List que esté a nil, y si lo encontrase, asigno esa posición del MainForm.Arr_List a la instancia que acabo de crear de List_General. Si no hay ningun nil en el Array, entonces sí que lo añado al final.

Código Delphi [-]
procedure TMainForm.Create_New_List;
var
  i : integer;
  Aux_L : Integer;
begin
 
  Screen.Cursor := crHourGlass;
 
  Aux_L := Length(Arr_List);
  if Aux_L = 0 then
    I := 0
  else begin
    for I := 0 to Aux_L - 1 do begin
      if Arr_List[i] = nil then break;
    end;
  end;
 
  if I >= Aux_L then begin
    SetLength(Arr_List,I+1);
    I := length(Arr_List)-1;
  end;
 
  Arr_List[i] := TList_General.Create(Self);
  Arr_List[i].FormStyle             := fsMDIChild;
  ....
  Arr_List[i].Pos_Array             := I;
  ....
  Arr_List[i].Show;
 
  Screen.Cursor := crDefault;
 
end;

Cada instancia de List_General tiene por lo tanto una variable pública Pos_Array.

Pienso que si le paso esta variable Pos_Array al Thread Calculate_Total, también podré hacer referencia dentro del Thread a la instancia concreta de List_General que quiera. Como tu bien dices, también podría pasar el Form en sí mismo como referencia.

Todavía no me ha quedado claro la otra cuestión, que a su vez te intento aclarar a ti.

El Thread Calculate_Total a su vez llama a otro procedimiento almacenado en una unit .pas .

Código Delphi [-]
procedure TCalculate_Total.Execute;
begin
 
  CTDatabase := TIBDatabase.Create(nil);
  CTDataBase.DatabaseName := DM0.IBDatabase1.DatabaseName;
  CTDataBase.LoginPrompt  := DM0.IBDatabase1.LoginPrompt;
  CTDataBase.Params       := DM0.IBDatabase1.Params;
  CTDataBase.SQLDialect   := 3;
  CTDataBase.Connected    := True;
 
  CTTransaction := TIBTransaction.Create(nil);
  CTTransaction.DefaultDataBase := CTDatabase;
  CTTransaction.StartTransaction;
 
  CTDataSet1 := TIBDataSet.Create(nil);
  CTDataSet1.Transaction := CTTransaction;
 
  CTDataSet2 := TIBDataSet.Create(nil);
  CTDataSet2.Transaction := CTTransaction;
 
  CTDataSet3 := TIBDataSet.Create(nil);
  CTDataSet3.Transaction := CTTransaction;
 
  CTDataSet4 := TIBDataSet.Create(nil);
  CTDataSet4.Transaction := CTTransaction;
 
  CTDataSetCheck  := TIBDataSet.Create(nil);
  CTDataSetCheck.Transaction  := CTTransaction;
 
  CTDataSetCheck2 := TIBDataSet.Create(nil);
  CTDataSetCheck2.Transaction := CTTransaction;
 
  CTDataSetCheck3 := TIBDataSet.Create(nil);
  CTDataSetCheck3.Transaction := CTTransaction;
 
  with CTDataSet1 do begin
    SelectSQL.Clear;
    SelectSQL.Add('..... ');
    ....
    ModifySQL.Clear;
    ModifySQL.Add('..... ');
    ....
    InsertSQL.Clear;
    InsertSQL.Add('..... ');
  end;

  ...
 
  if Type_Listing = 1 then Calculate_Detail(6, CTDataSet1, CTDataSetCheck,
     CTDataSetCheck2, CTDataSetCheck3, CTDataSet2, Random_No4, Today, Today); 
  ...
 
  CTTransaction.Active := False;
  CTDataBase.Close;
  CTDataBase.Free;
  CTTransaction.Free;
  CTDataSet1.Free;
  CTDataSet2.Free;
  CTDataSet3.Free;
  CTDataSetCheck.Free;
  CTDataSetCheck2.Free;
  CTDataSetCheck3.Free;

end;

El procedimiento Calculate_Detail, como decía, está en otra Unit diferente y puede ser llamado por otros muchos forms de mi aplicación, al igual que se llama a este procedimiento desde el propio Thread. Pienso que esto es posible, no ? Es correcto hacerlo así, no ?

Mi duda es cómo actualizo una variable del Thread (Calculate_Total) desde el procedimiento Calculate_Detail ?

Hasta ahora lo hacía tal y como indiqué en un hilo anterior
Código Delphi [-]
procedure Calculate_Detail(Modus: Integer; pDataSet1: TIBDataSet;
  pDataSetBDM: TIBDataSet; pDataSetBDM2: TIBDataSet; pDataSetBDM3: TIBDataSet;
  pDataSetBook: TIBDataSet; Random_No: Int64; StayOverFrom: TDate; StayOverTo: TDate);
begin
  ...
  Calculate_Total.Aux_Random := Aux_R1;
  ...
end;

Pero está claro que está mal hecho lo que hacía hasta ahora, porque en verdad no esta referiéndome a ninguna instancia en concreto del Thread Calculate_Total creado en cada List_General. No había declarado la variable Calculate_Total correctamente dentro de List_General.

Cómo puedo actualizar entonces la variable Aux_Random declarada como pública dentro del Thread Calculate_Total ? Cómo me puedo referir a cada instancia en concreto de Calculate_Total, que a su vez ha sido creada por cada instancia de List_General ?

Pensaba que podía ser igual que ponía en mi último post :
Código Delphi [-]
MainForm.Arr_List[i].Calculate_Total.Aux_Random := Aux_R1;
pero lo he probado y no me funciona.

Si pasase el Form (List_General) como referencia al Thread (Calculate_Total), y este Thread (Calculate_Total) a su vez se lo pasase al procedimiento Calculate_Detail, como sería posible la actualización desde Calculate_Detail de la variable Aux_Random declarada en el Thread Calculate_Total ?

.... que lío no ???

Gracias de nuevo !
__________________
Piensa siempre en positivo !
Responder Con Cita
  #4  
Antiguo 09-02-2011
Avatar de Chris
[Chris] Chris is offline
Miembro Premium
 
Registrado: abr 2007
Ubicación: Jinotepe, Nicaragua
Posts: 1.678
Poder: 21
Chris Va por buen camino
Creo que el problema es exactamente lo mismo que piensas. Estás compartiendo una variable global (Calculate_Total) entre las distintas instancias del form, por lo que al final todos trabajan con el mismo Thread. Creo que necesitarás declarar e implementar un nuevo constructor para TCalculate_Total que te permita pasarle un nuevo parámetro que indique cuál es el formulario padre.

Sin embargo, debes de saber que la biblioteca cliente de Firebird no es Thread Safe (hasta la versión 2.5), por lo que la independencia que crees estar creando es subliminal y que además talvez podría dar origen a problemas que sean muy difíciles de rastrear.

Saludos,
Chris
__________________
Perfil Github - @chrramirez - Delphi Blog - Blog Web

Última edición por Chris fecha: 09-02-2011 a las 18:38:15.
Responder Con Cita
  #5  
Antiguo 10-02-2011
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: 19.441
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
Cita:
Empezado por gluglu Ver Mensaje
Antes de nada, decirte que el último ZIP añadido no está accesible en estos momentos. El contenido es ilegible y da error. Así que no he podido revisar este último código que adjuntas.
Lo he vuelto a subir. No se porqué con segun qué programas utilizo para comprimir, luego a algunas personas les da problemas al descomprimir. Hay un .RAR.ZIP que hay que quitarle la extension ZIP y dejarlo en RAR.

Cita:
Empezado por gluglu Ver Mensaje
(1) Ya me queda claro que no declaré el Thread Calculate_Total en la unit List_General como private. Entiendo que en cualquier caso, también se podría declarar como público, no es verdad ?

(2) En el primer ejemplo tu utilizas el propio método Create para pasar los parámetros a cada Thread. Personalmente nunca lo he utilizado así y no sé si es mejor o peor.
(1) No es que no pueda ser público, simplemente es que si lo declaras como privado de alguna forma te aseguras de que nadie accede a él por error, porque desde fuera no es visible. Si está declarado como público significa que cualquiera puede acceder a él. Pero lo que es funcionar, debe funcionar igual.

(2) En este caso es cuestion de gustos. Yo utilizo en algunos casos el create para pasar pasar parámetros y en otros, primero hago el create y luego asigno valor a las propiedades. No hay diferencia es cuestión de gustos.

Cita:
Empezado por gluglu Ver Mensaje
Por lo tanto entiendo también que puedo pasar tanto la referencia de la instancia del Form List_General en concreto que ejecuta el Thread al propio Thread, o puedo pasar una variable Pos_Array que es la cual me indica la posición en el Array Arr_List declarado en el MainForm, y después hacer referencia al listado en concreto como MainForm.Arr_List[Pos_Array] y a continuación el elemento que quiera.
Lo que no tengo claro es que no te de problemas al acceder desde el Thread a cosas que hay fuera, como los formularios. Aunque los pasemos como parámetro, no quiere decir que no fallen al acceder. De ahí que acceder al MainForm, para luego al array, y desde ahí al formulario tenga bastantes número de dar problemas.

Cita:
Empezado por gluglu Ver Mensaje
El procedimiento Calculate_Detail, como decía, está en otra Unit diferente y puede ser llamado por otros muchos forms de mi aplicación, al igual que se llama a este procedimiento desde el propio Thread. Pienso que esto es posible, no ? Es correcto hacerlo así, no ?
También creo que te puede dar problemas. Para utilizar algo externo al thread utilizas el Synchronize, para evitar conflictos entre diferentes threads. Cuando accedes a este procedimiento y a todo lo que hay dentro, deberías asegurarte de que lo haces de forma exclusiva; Si no es así puedes obtener errores.

Cita:
Empezado por gluglu Ver Mensaje
Mi duda es cómo actualizo una variable del Thread (Calculate_Total) desde el procedimiento Calculate_Detail ?
El problema creo que no es cómo actualizar la variable (puede ser como en un procedimiento normal), sino que ese procedimiento se ejecute de forma "thread-safe", que creo que es lo que no estás asegurando ahora.

¿Porqué no colocas ese procedimiento Calculate_Detail como un procedimiento interno (private) del thread?
¿Es posible? Si no utiliza nada externo no debes tener problemas, y si utiliza algo externo para no poder ponerlo como privado, ese es el problema.

Un saludo.
__________________
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


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

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
Firebird AND Threads Abel Garcia Firebird e Interbase 21 19-03-2008 05:07:21
uso de threads JULIPO API de Windows 2 25-07-2007 16:09:06
Threads in DLL's Gianni Varios 0 20-07-2007 22:18:23
Threads zombies Archer Varios 1 25-09-2006 19:19:38
problemas con threads dentro de un componente elcigarra OOP 26 26-05-2005 04:29:35


La franja horaria es GMT +2. Ahora son las 08:33:37.


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