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
相关产品推荐
相关产品推荐

