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

TIdMessage.SaveToStream保存异常:跨线程传输后加载丢失MessageParts

解决TIdMessage保存到Stream后加载丢失MessageParts的问题

问题根源

你代码里的核心问题是保存到Stream后没有重置流的读取位置。SaveToStream执行完后,Stream的Position会停在流的末尾,此时直接调用LoadFromStream会从末尾开始读取,自然读不到任何内容,导致MessageParts.Count为0。

修复方案1:重置流位置

修改代码,在LoadFromStream前把流的Position设为0:

Log('Msg.MessageParts.Count='+Msg.MessageParts.Count.ToString,d_4); // 3 parts
AStream := TMemoryStream.Create;
try
  MSG.SaveToStream(AStream);
  // 重置流到起始位置
  AStream.Position := 0;

  MSG.Free;
  MSG := TIdMessage.Create(nil);
  MSG.LoadFromStream(AStream);
  Log('After Load: Msg.MessageParts.Count='+Msg.MessageParts.Count.ToString,d_4); // 现在应该是3 parts
finally
  AStream.Free;
end;

注意:记得用try...finally确保Stream被正确释放,避免内存泄漏。

修复方案2:直接使用Assign复制对象

如果只是需要完整复制TIdMessage对象,用Assign方法比流操作更高效且不易出错:

Log('Msg.MessageParts.Count='+Msg.MessageParts.Count.ToString,d_4); // 3 parts
var NewMsg: TIdMessage;
begin
  NewMsg := TIdMessage.Create(nil);
  try
    NewMsg.Assign(Msg);
    Log('After Assign: NewMsg.MessageParts.Count='+NewMsg.MessageParts.Count.ToString,d_4); // 3 parts
    // 把NewMsg传递到主线程使用
  finally
    // 注意:主线程使用完后再释放NewMsg,避免提前释放
    // NewMsg.Free;
  end;
end;

线程间传递对象时,要确保原对象在复制过程中不被其他线程修改,复制完成后再安全传递。

额外注意事项

如果是从IMAP获取的TIdMessage,确保在保存/复制前没有提前释放或修改MessageParts里的内容,比如不要手动调用MessageParts.Clear之类的操作。

内容的提问来源于stack exchange,提问作者Bart Kindt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 10:22:11