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

使用MemoryStream作为邮件附件发送时报Stream does not support reading异常如何解决

异常原因分析

核心根因:流被提前释放

你的代码存在两个关联问题导致MemoryStream在SmtpClient读取前就被销毁:

  • 首先MailWithAttachment方法签名是void,但内部使用了await调用异步方法,说明你实际代码中这个方法是async void类型。async void方法仅适合用作事件处理器,外部调用方无法等待它的执行完成,会导致using代码块在SendMailAsync还没完成流读取操作时就提前结束,MemoryStream被Dispose后就不再支持读取操作,直接抛出对应异常。
  • 就算你把方法改成async Task,如果上层调用这个方法时没有加await,也会出现同样的提前释放问题。

其他可能诱因

  • 你传入Attachment构造函数的流被其他业务代码提前修改了Position到末尾,读取的时候直接读到结尾误以为流不可读,不过你现有代码中已经显式设置了Position=0,这个概率较低。
  • 你简化的GetMemoryStream方法中如果存在其他操作,比如返回的是已经被Dispose的MemoryStream,也会触发这个异常。
修复方案
  1. 修正MailWithAttachment方法的签名,改为返回Task,不要用async void:
// 修改前
public void MailWithAttachment()
// 修改后
public async Task MailWithAttachment()
  1. 所有调用MailWithAttachment的地方都加上await,确保using块会等待整个邮件发送流程完成后再释放流:
// 调用示例
await MailWithAttachment();
  1. 可选兜底方案:如果确实无法避免流提前释放,可以在创建Attachment的时候直接把流内容读出来传入,避免依赖外部流的生命周期:
// 创建Attachment时将流内容复制到新的MemoryStream,不依赖外部传入流的生命周期
using var streamCopy = new MemoryStream();
await stream.CopyToAsync(streamCopy);
streamCopy.Position = 0;
var attachment = new Attachment(streamCopy, ct);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 03:00:01