multithreading - sincronizar - delphi tthread
Simple Thread Sample Delphi (2)
Puede encontrar muchos ejemplos en la red de hilos. La única característica especial, si está utilizando conexiones ADO dentro del subproceso, es que no puede compartir la misma conexión.
Cada hilo debe crear su propia conexión , de lo contrario son iguales (deben seguir las mismas reglas que cualquier otro hilo).
Una muestra que he usado es esta:
TADOSQLThread = class(TThread)
private
FADOQ: TADOQuery; // Internal query
FSQL: string; // SQL To execute
FID: integer; // Internal ID
public
constructor Create(CreateSuspended:Boolean; AConnString:String;
ASQL:string; IDThread:integer);
destructor Destroy; override;
procedure Execute(); override;
property ID:integer read FID write FID;
property SQL:string read FSQL write FSQL;
property ADOQ:TADOQuery read FADOQ write FADOQ;
end;
El creador Create está anulado y se ve así:
constructor TADOSQLThread.Create(CreateSuspended:Boolean; AConnString:String;
ASQL:string; IDThread:integer);
begin
inherited Create(CreateSuspended);
// ini
Self.FreeOnTerminate := False;
// Create the Query
FADOQ := TAdoquery.Create(nil);
// assign connections
FADOQ.ConnectionString := AConnString;
FADOQ.SQL.Add(ASQL);
Self.FID := IDThread;
Self.FSQL:= ASQL;
end;
Y el método de ejecución es muy simple:
procedure TADOSQLThread.Execute();
begin
inherited;
try
// Ejecutar la consulta
Self.FADOQ.Open;
except
// Error al ejecutar
...Error treattement
end;
end;
Para comenzar y crear un hilo, puede usar un código similar a este:
//crear el Thread
th := TADOSQLThread.Create(True, mmConnection.Lines.Text, ASQL, AId);
// internal for me (for controled the number of active threads and limete it)
inc(numThreads);
// evento finalizacion
th.OnTerminate := TerminateThread;
// Ejecutarlo
th.Resume;
He creado un método TerminateThread que recibe el control de los hilos cuando terminan. Lo único diferente a otros hilos es el problema de conexión. Debe crear una nueva conexión en cada hilo. No puede compartir las mismas ADOConnections con otros.
Espero que este ejemplo te sea útil.
Saludos
Soy nuevo con estas cosas de Threading en Delphi. entonces, estoy tratando de hacer una consulta simple que haga un poco de llamada para la base de datos y tome un poco de tiempo, así que quiero alertar al usuario de que hay un proceso en segundo plano y tengo que ser paciente.
Probé muchas muestras, pero ninguna de ellas me funciona. ¿Podría alguien mostrarme una muestra simple que podría funcionar?
Sé que tengo que declarar un tipo de TThread, con Create y Override Execute ... etc. pero desde ese momento estoy perdido ...
Usando Delphi 7, SQL Server 2005 y ADO, Windows XP sp3.-
Gracias.
Sí, declaras un nuevo tipo que hereda de TThread:
TMyWorkerThread = class(TThread)
end;
A continuación, agrega una sustitución de función para Execute ():
TMyWorkerThread = class(TThread)
public
procedure Execute; override;
end;
Se llamará a ese procedimiento cuando inicie su hilo. Se ejecutará en paralelo con su programa principal. Vamos a escribirlo.
procedure TMyWorkerThread.Execute;
begin
//Here we do work
DoSomeWork();
DoMoreWork();
//When we exit the procedure, the thread ends.
//So we don''t exit until we''re done.
end;
¿Como usar esto? Supongamos que desea comenzar a trabajar cuando el usuario hace clic en el botón. Usted escribe un controlador OnClick:
procedure TMainForm.Button1Click(Sender: TObject);
begin
TMyWorkerThread.Create(false);
end;
Eso es. Después de que el usuario haga clic en el botón, el hilo comienza y continúa haciendo lo que sea que haya escrito en Ejecutar. Si el usuario vuelve a hacer clic en el botón, se iniciará otro, y luego otro, uno por cada clic. Todos se ejecutarán en paralelo, cada uno haciendo todo lo que está escrito en Execute () y luego terminando.
Digamos que desea verificar si el trabajo terminó. Para eso, tendrás que guardar la referencia a tu hilo en alguna parte:
TMainForm = class(TForm)
{...skipped...}
public
MyWorkerThread: TThread;
end;
procedure TMainForm.Button1Click(Sender: TObject);
begin
//This time we make sure only one thread can be started.
//If one thread have been started already, we don''t start another.
if MyWorkerThread<>nil then
raise Exception.Create(''One thread have already been started!'');
MyWorkerThread := TMyWorkerThread.Create(false);
end;
procedure TMainForm.Button2Click(Sender: TObject);
begin
//If the work is not over yet, we display message informing the user we''re still working
if (MyWorkerThread<>nil) and (WaitForSingleObject(MyWorkerThread.Handle, 0)<>WAIT_OBJECT_0) then
MessageBox(Self.Handle, pchar("The work is not yet done!"), pchar("Still running"), MB_OK);
end;
Como puede ver, estamos verificando si un hilo todavía se está ejecutando llamando a una función de Windows llamada WaitForSingleObject. Esta función espera hasta que el hilo termine de funcionar, o el tiempo de espera haya expirado, y cuando especificamos el tiempo de espera de 0, simplemente existe inmediatamente si el hilo no se ha terminado aún.