PDA

Visualizza la versione completa : [Delphi 7] Utilizzo dei Threads


Mco2983
16-04-2010, 16:15
Ciao a tutti!

Per un'applicazione che sto realizzando ho implementato una funzione di invio email verso indirizzi prelevati da un'archivio.
Queste email devono essere inviate ad una ad una, per cui devo x forza eseguire il classico ciclo "while not eof".
Ma siccome questi indirizzi sono parecchi, ho pensato di inserire i threads per evitare temp infiniti.

Il suddetto ciclo è semplicemente così:

...
C:=0;
IndexMail:=0;
while not DM1.Temail.Eof do
begin
Inc(C);
ValidEmail:=TValidEmail.Create(True);
ValidEmail.FreeOnTerminate:=true;
ValidEmail.TabMls:=DM1.Temail;
ValidEmail.Email:=DM1.TemailEmail.AsString;
ValidEmail.C:=C;
ValidEmail.N:=DM1.Temail.RecordCount;
ValidEmail.Resume;
DM1.Temail.Next;
end;
...

Mentre di seguito posto il codice relativo al thread:

type
TValidEmail = class(TThread)
private
Status: string;
fEmail: string;
fTabMls: TADOTable;
procedure SetEmail(const Value: string);
procedure SetTabMls(const Value: TADOTable);
protected
procedure Execute; override;
procedure VisuaStatus;
procedure ShowProgress;
procedure InviaMail;
procedure FineCiclo;
public
C,N: integer;
property Email: string read fEmail write SetEmail;
property TabMls: TADOTable read fTabMls write SetTabMls;
end;

procedure TValidEmail.Execute;
begin
Status:='In analisi email '+IntToStr(C)+' di '+IntToStr(N)+': '+fEmail;
Synchronize(VisuaStatus);
ConvalidaMail;
Synchronize(FineCiclo);
end;

procedure TValidEmail.VisuaStatus;
begin
FrmMain.StatusBar1.Panels[0].Text:=Status;
FrmMain.ListaOp.Lines.Add(Status);
end;

procedure TValidEmail.ShowProgress;
begin
FrmMain.Barra.Position:=FrmMain.Barra.Position+1;
end;

procedure TValidEmail.InviaMail;
begin
...
SMTP:=TIdSMTP.Create(nil);
SMTP.Port:=25;
SMTP.Host:=IP;
SMTP.AuthenticationType:=atNone;
try
try
SMTP.Connect(-1);
...
except
Status:='Email '+fEmail+': Errore di Connessione: '+SMTP.LastCmdResult.TextCode+' - '+SMTP.LastCmdResult.Text.Text;
Synchronize(VisuaStatus);
end;
finally
if SMTP.Connected then SMTP.Disconnect;
end;
SMTP.Free;
end;

procedure TValidEmail.FineCiclo;
begin
Inc(IndexMail);
Synchronize(ShowProgress);
Status:='Email '+IntToStr(C)+' di '+IntToStr(N)+' analizzata';
Synchronize(VisuaStatus);
if (IndexMail >= TotalMail) then // Si verifica quando ho inviato tutte le mail, x avvisare l'utente del termine della procedura
begin
FrmMain.TabSheet2.Enabled:=true;
FrmMain.BitBtn3.Enabled:=true;
FrmMain.BitBtn11.Enabled:=true;
FrmMain.BitBtn12.Enabled:=true;
FrmMain.Barra.Position:=FrmMain.Barra.Max;
DM1.Temail.Refresh;
DM1.Temail.First;
FrmMain.ContaMail;
Status:='Ciclo di validazione terminato';
FrmMain.StatusBar1.Panels[0].Text:=Status;
FrmMain.ListaOp.Lines.Add(Status);
Screen.Cursor:=crDefault;
Application.MessageBox('Processo di validazione Email terminato','Emailer',MB_ICONINFORMATION);
FrmMain.ListaOp.Lines.SaveToFile(ExtractFilePath(A pplication.ExeName)+'Logs\'+FormatDateTime('yyyy-mm-dd_hh-nn',Now)+'.log');
end;
end;

Così come l'ho realizzato funziona tutto correttamente tranne in un caso: se si genera l'exception che ho gestito nella procedure InviaMail, il controllo di quel thread specifico si blocca e non va oltre, cioè non passa all'interno della procedure successiva FineCiclo.
Cosa devo fare per risolvere queto problema?

Grazie x la collaborazione,
Maurizio

Loading