Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi Can';不要使用Indy,冻结程序发送电子邮件_Delphi_Delphi 2010_Email Attachments_Indy - Fatal编程技术网

Delphi Can';不要使用Indy,冻结程序发送电子邮件

Delphi Can';不要使用Indy,冻结程序发送电子邮件,delphi,delphi-2010,email-attachments,indy,Delphi,Delphi 2010,Email Attachments,Indy,当我试图用indy发送带有附件的电子邮件时,我的程序冻结了,我不知道为什么。 这是我用来发送电子邮件的表单的完整代码 unit Dok_sutisana; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, IdMessage, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient,

当我试图用indy发送带有附件的电子邮件时,我的程序冻结了,我不知道为什么。 这是我用来发送电子邮件的表单的完整代码

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.

我希望通过这一点,我可以为我的问题获得一些帮助。

Indy使用阻塞操作,而您正在主UI线程的上下文中使用Indy。因此,当
tidstp
正忙时,您的主线程将被阻止处理新邮件,从而出现应用程序冻结的现象,直到
tidstp
完成

要避免冻结,您可以:

  • (首选解决方案)将
    tidstp
    代码移动到单独的工作线程中

  • 在您的表单上放置一个
    tid防冻剂
    成分。这将允许主消息队列在其他Indy组件在主线程中运行时继续处理新消息


  • 为了更好地测量,您还应该设置
    tidstp.ConnectTimeout
    tidstp.ReadTimeout
    属性,以便
    Connect()
    Send()
    不会长时间阻塞。如果发生超时,将引发相应的异常以中止操作。

    我从代码中删除了ADO的使用,并为我的电子邮件帐户使用了硬编码值(出于安全原因,此处已删除-您可以将占位符替换为工作帐户)

    此代码有效-它发送一个附件

    我还:

    • 在连接周围添加了try/finally,以确保在发送引发异常时释放连接
    • 添加了Lemy提到的ConnectTimeout选项
    • 已清除电子邮件正文。在添加新内容之前(否则您将得到测试的多个副本)
    • 还需要删除以前的附件,否则您的第二封电子邮件将以第一封电子邮件的附件结尾

      IdSMTP1.Host := '******';
      IdSMTP1.Port := 25;
      IdSMTP1.Username:= '******@gmail.com';
      IdSMTP1.Password:='******';
      IdMessage1.From.Address := '******';
      IdMessage1.From.Name:= '******';
      IdMessage1.Recipients.EMailAddresses := '******';
      IdMessage1.Subject := '******';
      IdMessage1.Body.Clear; // Clear the email body
      IdMessage1.Body.Add('******');
      s:= GetCurrentDir + '\******';
      IdMessage1.MessageParts.Clear;
      TIdAttachmentFile.Create(IdMessage1.MessageParts, s ) ;
      
      IdSMTP1.ConnectTimeout := 2400 ;
      IdSMTP1.Connect();
      try
          IdSMTP1.Send(IdMessage1) ;
      finally
          IdSMTP1.Disconnect;
      end; 
      
    由于此简单示例有效,您的问题可能是:

    • 表中的电子邮件名称/密码/值不正确
    • 防病毒软件包,防止您的程序访问TCP
    • 试图使用ISP未提供的电子邮件帐户

    当我更改ISP时,旧的ISP不起作用(访问需要SMTPS),但当我交换使用宽带供应商提供的电子邮件帐户时,这不需要SMTPS,而是在普通SMTP上工作,因为它在他们的网络中,因此受信任

    您是否尝试使用调试器单步执行代码?可能有助于准确了解锁定的步骤。此外,您还需要尝试…最后围绕连接/断开连接和内存创建/释放。可能是第一次通过您连接但未断开连接,然后您将不得不等待连接超时。@DavidG锁定发生在tidstp中。idsmtp中的connect函数使用此库时,我有其他行:“IdSMTP1.NeedAuthentication:=false;”和“IdSMTP1.UseTLS:=emNOTLSSupport”。我怀疑您可以在连接之前尝试第一行,看看会发生什么。在您的行“IdSMTP1.connect”之前添加“IdSMTP1.NeedAuthentication:=false;”。请注意,您的代码无法使用“Connect()”进行编译,因为这不是有效的delphi pascal。您需要提供实际的代码。可能是为什么质询被搁置了。@DavidG我到底需要在哪里添加质询?(我对这一切不太了解)虽然你经历了这么多努力很好,但这并不能回答问题。正确的答案是Indy正在阻塞,因此您的代码将停止,直到调用
    IdSMTP1.Send
    返回为止。Remy的答案中包含正确的信息,即使用单独的线程或使用
    tid防冻液
    (按优先顺序)防止阻塞主(UI)线程。(海报的代码也会发送一个附件;问题是如何防止它在执行此操作时冻结用户界面。)我添加了
    tid防冻液
    ,并尝试再次发送电子邮件。程序仍然无法运行,但我可以按下发送按钮并引发异常,
    eid已连接
    ,程序无法继续。
    EIdAlreadyConnected
    在调用
    Connect()
    时引发,而
    connected
    为true。请记住,如果
    IOHandler.InputBuffer
    中有未读数据,即使基础套接字已关闭,
    Connected
    也可能为真。因此,如果您需要在活动连接期间关闭套接字,然后重新连接,请确保在再次调用
    Connect()
    之前清除
    InputBuffer
    。如果发生连接,为什么消息没有发送?鉴于您目前提供的详细信息有限,无法回答这个问题。实际冻结发生在哪里?在
    Connect()
    Send()
    上?您连接到的实际
    端口是什么?问题可能是安全性问题,我的程序是使用来自的代码运行的