Échantillon De Fil Simple Delphi
je suis nouveau avec ce truc de Threading à Delphi. donc, j'essaie de faire une simple application de requête qui fait un peu appel à la base de données et prend un peu de temps, donc je veux alerter l'utilisateur qu'il y a un processus de fond et doit être patient.
j'ai essayé beaucoup d'échantillons, mais aucun d'eux ne fonctionne pour moi, S'il Vous Plaît, quelqu'un pourrait me montrer un échantillon simple qui pourrait fonctionner?
je sais que je dois déclarer un Type de TThread, avec Create et Override Execute... etc.. mais depuis que je suis perdu...
en utilisant Delphi 7, SQL Server 2005 et ADO, Windows XP sp3.-
Merci.
2 réponses
Vous pouvez trouver de nombreux exemples sur le web de fils. La seule particularité, si vous utilisez des connexions ADO à l'intérieur du Thread, est que vous ne pouvez pas partager la même connexion.
Chaque thread doit créer sa propre connexion, sinon ils sont égaux (doit suivre les mêmes règles que n'importe quel autre thread.)
Un exemple que j'ai utilisé est:
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;
le constructeur Create est dépassé, et ressemble à ceci:
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;
Et la méthode execute est très simple:
procedure TADOSQLThread.Execute();
begin
inherited;
try
// Ejecutar la consulta
Self.FADOQ.Open;
except
// Error al ejecutar
...Error treattement
end;
end;
pour démarrer et créer un thread, vous pouvez utiliser un code similaire à celui-ci:
//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;
j'ai créé un TerminateThread méthode qui reçoit le contrôle des fils quand ils finissent. La seule différence avec les autres threads est le problème de connexion. Vous devez créer une nouvelle connexion sur chaque fil, il ne peut pas partager les mêmes ADOConnections avec les autres.
J'espère que cet exemple sera utile pour vous.
Cordialement
Yup, vous déclarez un nouveau type qui hérite de TThread:
TMyWorkerThread = class(TThread)
end;
ensuite, vous ajoutez une fonction override pour Execute ():
TMyWorkerThread = class(TThread)
public
procedure Execute; override;
end;
Cette procédure sera appelée lorsque vous démarrez votre fil. Il sera exécuté en parallèle avec votre programme principal. Nous allons l'écrire.
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;
Comment l'utiliser? Disons que vous voulez commencer à travailler lorsque l'utilisateur clique sur le bouton. Vous écrivez un handler OnClick:
procedure TMainForm.Button1Click(Sender: TObject);
begin
TMyWorkerThread.Create(false);
end;
C'est ça. Après que l'utilisateur cliquez sur le bouton, votre fil commence et continue à faire ce que vous avez écrit dans Execute. Si l'utilisateur clique à nouveau sur le bouton, un autre thread démarre, puis un autre - un à chaque clic. Ils s'exécuteront tous en parallèle, chacun faisant tout ce qui est écrit dans Execute() et ensuite se terminant.
disons que vous voulez vérifier si le travail est terminé. Pour cela, vous devrez stocker la référence à votre fil quelque part:
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;
Comme vous le voyez, nous vérifions si un thread est toujours en cours d'exécution en appelant une fonction Windows appelée WaitForSingleObject. Cette fonction attend que le thread fonctionne, ou que le timeout soit écoulé, et comme nous spécifions le timeout de 0, elle existe juste immédiatement si le thread n'est pas encore terminé.