Fórum Problema com Thread #437079
14/03/2013
0
Tenho uma Thread em minha aplicação que faz envio de Email!
porem esta Thread usa os componentes que estão na tela que chamou a Thread!
o problema esta na seguinte situação:
da minha tela principal chamo o método da Thread varias vezes, pois o cliente vai clicando em enviar Email e o sistema vai chamando a Thread para enviar o Email...
ou seja, varias instancias ficam tentando enviar o Email!
quando meu cliente fecha a tela principal, todos os emails que ainda não foram enviados pois a Thread ainda não terminou a execução não serão enviados!
preciso impedir meu cliente de fechar a tela principal enquanto todas as threads não terminarem suas execuções!
aqui esta o código da minha Thread:
unit Thread;
interface
uses
Classes, spdNFe, ActiveX, FatNFE, clipbrd, SysUtils;
type
Enviaemail = class(TThread)
private
Nfeenvia: TspdNFe;
{ Private declarations }
protected
procedure Execute; override;
public
constructor enviar(Nfe: TspdNFe; SID_nota, SID_Numero : String);
end;
var
SIdentificador, SNumero : string;
implementation
{ Enviaemail }
constructor Enviaemail.enviar(Nfe: TspdNFe; SID_nota, SID_Numero : String);
begin
Create(False);
Nfeenvia := Nfe;
SIdentificador := SID_nota;
SNumero := SID_Numero;
FreeOnTerminate := True;
WaitFor;
end;
procedure Enviaemail.Execute;
begin
CoInitialize(nil);
Try
Nfeenvia.EnviarNotaDestinatario(SIdentificador);
Form_NFe.RzStatusPane_Informa.Caption := 'Email da Nota: '+SNumero+' enviado com sucesso ';
Form_NFe.RzRichEdit_LogEmail.Lines.Add('Email da Nota: '+SNumero+' enviado com sucesso ');
//FatNFE.SStatus := 'Enviado com Sucesso';
Except
on E: Exception do
begin
Form_NFe.RzStatusPane_Informa.Caption := 'Erro ao enviar o Email da Nota: '+SNumero+' ';
Form_NFe.RzRichEdit_LogEmail.Lines.Add('Erro ao enviar o Email da Nota: '+SNumero+' ');
Form_NFe.RzStatusPane_Informa.Blinking := True;
//FatNFE.SStatus := 'Erro ao enviar nota';
Clipboard.AsText := E.message;
end;
end;
{ Place thread code here }
end;
end.
Aqui esta a chamada:
procedure TForm_NFE.vClick(Sender: TObject);
var
email : EnviaEmail;
begin
try
email := EnviaEmail.enviar(NFe, Q_Notas_Prontasid_a03.AsString, Q_Notas_Prontasnnf_b08.AsString);
except
on E: Exception do
begin
ShowMessage('Atenção: Falha no Email.' +
#13 + E.Message);
raise;
end;
end;
end;
Alguma sugestão?
Km Sistemas
Curtir tópico
+ 0Post mais votado
14/03/2013
Você poderia utilizar uma especie de contador, que a cada thread criada, adicione um neste contador. No momento em que envia o email, diminui um.
Na tentativa de fechar o form, você verifica se este contador é maior que zero.
É só uma ideia...
Luiz Menin
Gostei + 1
Mais Posts
14/03/2013
Luiz Menin
Dê uma olhada neste artigo: http://www.planetadelphi.com.br/dica/6353/construindo-threads-com-delphi
Gostei + 0
14/03/2013
Francisco Macário
Bom para impedir o fechamento do FORM utilize o evento OnCloseQuery do FORM, fazendo uso da variavel CanClose.
Exemplo disponivel em Planeta Delphi >
[url]http://www.planetadelphi.com.br/dica/4179/impedir-que-o-form-seja-fechado-com-alt+f4[/url]
Assim voce so deixara CanClose = true caso nao exista nenhum Thread em execução.
Para isso implemente algum tipo de controle, como um contador, etc.
Espero que ajude.
Gostei + 0
14/03/2013
Km Sistemas
Dê uma olhada neste artigo: http://www.planetadelphi.com.br/dica/6353/construindo-threads-com-delphi
Alterei o código da Thread para ficar da seguinte forma:
unit Thread;
interface
uses
Classes, spdNFe, ActiveX, FatNFE, clipbrd, SysUtils;
type
Enviaemail = class(TThread)
private
Nfeenvia: TspdNFe;
msg: String;
{ Private declarations }
protected
procedure Execute; override;
procedure IncLabel; virtual;
public
constructor enviar(Nfe: TspdNFe; SID_nota, SID_Numero : String);
end;
var
SIdentificador, SNumero : string;
implementation
{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example,
Synchronize(UpdateCaption);
and UpdateCaption could look like,
procedure Enviaemail.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end; }
{ Enviaemail }
constructor Enviaemail.enviar(Nfe: TspdNFe; SID_nota, SID_Numero : String);
begin
Create(False);
Nfeenvia := Nfe;
SIdentificador := SID_nota;
SNumero := SID_Numero;
FreeOnTerminate := True;
end;
procedure Enviaemail.Execute;
begin
CoInitialize(nil);
Try
Nfeenvia.EnviarNotaDestinatario(SIdentificador);
msg := 'Email da Nota: '+SNumero+' enviado com sucesso ';
Synchronize(IncLabel);
//Form_NFe.RzStatusPane_Informa.Caption := 'Email da Nota: '+SNumero+' enviado com sucesso ';
//Form_NFe.RzRichEdit_LogEmail.Lines.Add('Email da Nota: '+SNumero+' enviado com sucesso ');
Except
on E: Exception do
begin
msg := 'Erro ao enviar o Email da Nota: '+SNumero+' ';
//Form_NFe.RzStatusPane_Informa.Caption := 'Erro ao enviar o Email da Nota: '+SNumero+' ';
//Form_NFe.RzRichEdit_LogEmail.Lines.Add('Erro ao enviar o Email da Nota: '+SNumero+' ');
Form_NFe.RzStatusPane_Informa.Blinking := True;
Clipboard.AsText := E.message;
end;
end;
{ Place thread code here }
end;
procedure Enviaemail.IncLabel;
begin
Form_NFe.RzStatusPane_Informa.Caption := msg;
Form_NFe.RzRichEdit_LogEmail.Lines.Add(msg);
{ o Contador será executado em modo protegido por uma Seção Critica do Windows}
end;
end.
Porém ainda continua fechando a tela sem terminar de enviar os Email's!
Como faço para verificar se ainda tem alguma Thread sendo executada?
Gostei + 0
14/03/2013
Km Sistemas
Bom para impedir o fechamento do FORM utilize o evento OnCloseQuery do FORM, fazendo uso da variavel CanClose.
Exemplo disponivel em Planeta Delphi >
[url]http://www.planetadelphi.com.br/dica/4179/impedir-que-o-form-seja-fechado-com-alt+f4[/url]
Assim voce so deixara CanClose = true caso nao exista nenhum Thread em execução.
Para isso implemente algum tipo de controle, como um contador, etc.
Espero que ajude.
Com relação a impedir a form de fechar ta tranquilo... o problema é saber quando pode fechar?
Ou seja, todas as instancias da Thread já terminaram sua execução...
Gostei + 0
14/03/2013
Francisco Macário
Gostei + 0
14/03/2013
Francisco Macário
Gostei + 0
14/03/2013
Km Sistemas
Você poderia utilizar uma especie de contador, que a cada thread criada, adicione um neste contador. No momento em que envia o email, diminui um.
Na tentativa de fechar o form, você verifica se este contador é maior que zero.
É só uma ideia...
Essa ideia parece ser simples de implementar! Vou tentar fazer desta forma!
Gostei + 0
14/03/2013
Luiz Menin
Gostei + 0
18/11/2015
Km Sistemas
Incrementando uma variável e cada nova instancia e decrementando no termino da execução...
Grato!
Gostei + 0
18/11/2015
Luiz Menin
Incrementando uma variável e cada nova instancia e decrementando no termino da execução...
Grato!
Fico feliz pelo feedback e por você ter conseguido resolver!
Obrigado.
Gostei + 1
Clique aqui para fazer login e interagir na Comunidade :)