Search code examples
delphidelphi-2010email-attachmentsindy

Can't send email using Indy, freezes program


When i try to send an email with attachment using indy my program freezes and i don't know why. Here's the full code for the form i'm using for sending emails.

unit Dok_sutisana;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, IdMessage, IdBaseComponent, IdComponent, IdTCPConnection,
IdTCPClient, IdExplicitTLSClientServerBase, IdMessageClient, IdSMTPBase,
IdSMTP, StdCtrls, Buttons, ComCtrls, IdAttachmentFile;

type
TForm14 = class(TForm)
  Edit1: TEdit;
  Edit2: TEdit;
  Label1: TLabel;
  Label2: TLabel;
  BitBtn1: TBitBtn;
FontDialog1: TFontDialog;
RichEdit1: TRichEdit;
IdSMTP1: TIdSMTP;
IdMessage1: TIdMessage;
BitBtn2: TBitBtn;
procedure BitBtn2Click(Sender: TObject);
procedure BitBtn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
 end;

var
 Form14: TForm14;

 implementation

 uses Autentif, EDGA;

{$R *.dfm}

procedure TForm14.BitBtn1Click(Sender: TObject);
begin
if FontDialog1.Execute() then
RichEdit1.Font:=FontDialog1.Font;
end;

procedure TForm14.BitBtn2Click(Sender: TObject);
var s:string;
begin
form3.ADOTable1.Active:=true;
//setup SMTP
IdSMTP1.Host := form3.adotable1['smtp'];
IdSMTP1.Port := form3.adotable1['ports'];
IdSMTP1.Username:= '******@gmail.com';
IdSMTP1.Password:='******';

//setup mail message
IdMessage1.From.Address := form3.adotable1['e-pasts'];
IdMessage1.From.Name:= form3.adotable1['Vards']+' '+ form3.adotable1['Uzvards'];
IdMessage1.Recipients.EMailAddresses := edit1.Text;;

IdMessage1.Subject := edit2.Text;
IdMessage1.Body.Add(RichEdit1.Text + form3.ADOTable1['paraksts']);
s:= GetCurrentDir + form1.ADOTable1['Dok_adr'];
TIdAttachmentFile.Create(IdMessage1.MessageParts, s ) ;

//send mail

IdSMTP1.Connect() ;
IdSMTP1.Send(IdMessage1) ;
IdSMTP1.Disconnect;
IdMessage1.Free;
IdSMTP1.Free;

form3.ADOTable1.Active:=false;
Form14.Close;
end;

end.

I hope that whit this I can get some help for my problem.


Solution

  • Indy uses blocking operations, and you are using Indy in the context of the main UI thread. So while TIdSMTP is busy, your main thread is blocked from processing new messages, giving the appearance of an app freeze, until TIdSMTP is finished.

    To avoid the freezing, you can either:

    1. (preferred solution) Move your TIdSMTP code into a separate worker thread.

    2. Drop a TIdAntiFreeze component onto your Form. This will allow the main message queue to continue processing new messages while other Indy components are operating in the main thread.

    For good measure, you should also set the TIdSMTP.ConnectTimeout and TIdSMTP.ReadTimeout properties so Connect() and Send() do not block for long periods of time. If a timeout occurs, an appropriate exception will be raised to abort the operation.