You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi升级至11.3后Indy发送网络共享附件速度异常求助

问题排查与优化方案

一、网络共享附件发送缓慢问题排查

核心原因推测

  1. Indy默认网络文件读取逻辑缺陷:TIdAttachmentFile直接读取网络共享文件时,默认使用较小的IO缓冲(通常32KB),导致频繁发起跨网络IO请求,叠加网络延迟后总耗时剧增。
  2. Delphi 11.3 RTL文件API变动:升级后RTL对SMB协议的文件访问策略调整,默认缓存机制不适合网络共享文件,加剧读取等待。
  3. 主线程阻塞的调度影响:主线程执行同步发送时,系统对其网络IO的调度优先级低于后台线程,进一步拉长等待时间。

可疑代码点(基于常规Indy邮件实现)

若你的代码是直接通过共享路径创建附件,类似以下写法,这就是核心低效点:

vMsgBuilder := TIdMessageBuilderHtml.Create;
try
  vMsgBuilder.plainText.Text := '邮件内容';
  vMsgBuilder.Attachments.Add('\\server\share\file1.txt');
  vMsgBuilder.Attachments.Add('\\server\share\file2.txt');
  vMsgBuilder.FillMessage(vIdMessage);
finally
  vMsgBuilder.Free;
end;
vIdSMTP.Send(vIdMessage);

解决措施

  1. 本地缓存后发送:先将共享文件复制到本地临时目录,避免直接跨网络读取:
    var
      TempFile1, TempFile2: string;
    begin
      TempFile1 := TPath.GetTempFileName;
      TempFile2 := TPath.GetTempFileName;
      try
        CopyFile(PChar('\\server\share\file1.txt'), PChar(TempFile1), False);
        CopyFile(PChar('\\server\share\file2.txt'), PChar(TempFile2), False);
        // 用临时文件创建附件
        vMsgBuilder.Attachments.Add(TempFile1);
        vMsgBuilder.Attachments.Add(TempFile2);
        vMsgBuilder.FillMessage(vIdMessage);
        vIdSMTP.Send(vIdMessage);
      finally
        DeleteFile(TempFile1);
        DeleteFile(TempFile2);
      end;
    end;
    
  2. 增大Indy文件读取缓冲:手动调整TIdAttachmentFile的FileBufferSize,减少IO次数:
    var
      Attachment: TIdAttachmentFile;
    begin
      Attachment := TIdAttachmentFile.Create(vIdMessage.MessageParts, '\\server\share\file1.txt');
      Attachment.FileBufferSize := 1024 * 1024; // 设置为1MB缓冲
      // 第二个附件同理
    end;
    
  3. 后台线程执行发送:将邮件发送逻辑放到后台线程,避免阻塞主线程,同时提升网络IO调度优先级:
    TTask.Run(procedure
              begin
                // 邮件发送完整逻辑放在此处
                // 若需更新UI,用TThread.Synchronize或TThread.Queue同步
              end);
    

二、纯文本带附件的更优Indy用法

TIdMessageBuilderHtml是为HTML邮件设计的,纯文本场景下直接操作TIdMessage更高效,无需经过HTML构建层:

示例代码

var
  vIdMessage: TIdMessage;
  vIdSMTP: TIdSMTP;
begin
  vIdMessage := TIdMessage.Create(nil);
  try
    vIdMessage.From.Address := 'sender@domain.com';
    vIdMessage.Recipients.Add('recipient@domain.com');
    vIdMessage.Subject := '纯文本邮件带附件';
    // 设置纯文本内容
    vIdMessage.Body.Text := '这是纯文本邮件内容';
    // 直接添加附件,无需构建器
    TIdAttachmentFile.Create(vIdMessage.MessageParts, 'local_file.txt');
    TIdAttachmentFile.Create(vIdMessage.MessageParts, '\\server\share\file.txt');

    vIdSMTP := TIdSMTP.Create(nil);
    try
      vIdSMTP.Host := 'smtp.domain.com';
      vIdSMTP.Port := 587;
      vIdSMTP.Username := 'your_username';
      vIdSMTP.Password := 'your_password';
      vIdSMTP.Connect;
      try
        vIdSMTP.Send(vIdMessage);
      finally
        vIdSMTP.Disconnect;
      end;
    finally
      vIdSMTP.Free;
    end;
  finally
    vIdMessage.Free;
  end;
end;

优势

  • 跳过HTML构建器的冗余逻辑,减少对象创建和内存开销。
  • 直接操作TIdMessage的核心属性,逻辑更简洁,性能更优。

内容的提问来源于stack exchange,提问作者Roland Bengtsson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 16:22:47