我使用以下代码将文件附加到电子邮件中。
msg = new MailMessage();
using (strMem = new MemoryStream((byte[])attDr["filedata"]))
{
using (strWriter = new StreamWriter(strMem))
{
strWriter.Flush(); strMem.Position = 0;
using (attachment = new Attachment(strMem, attDr["filename"].ToString()))
{
msg.Attachments.Add(attachment);
}
}
}
...
...
msg.Send(); //Error: System.ObjectDisposedException: Cannot access a closed Stream.
错误消息是://错误:System.ObjectDisposedException:无法访问已关闭的流
我猜测“USING”语句在退出块时关闭流。但是为什么“Attacments.Add()”没有制作自己的流副本?
答案 0 :(得分:39)
Send()方法将访问附件以将它们嵌入到邮件消息中。这就是kaboom,内存流被处理掉了。您需要使用语句移动内部的Send()调用,以便在发送消息之后 之前不会释放流。
这里没有必要提到使用,因为内存流没有任何需要处理的非托管资源,总是让我遇到麻烦。所以我不会提起这件事。
答案 1 :(得分:12)
当我处理创建MailMessage的场景与发送分开并且可能具有多个附件时,我发现了一个解决方案是使用List of MemoryStream对象
// Tuple contains displayName and byte[] content for attachment in this case
List<Tuple<string,byte[]>> attachmentContent;
MailMessage email = BuildNativeEmail(requestObject, out attachmentContent);
List<MemoryStream> streams = new List<MemoryStream>();
foreach(Tuple<string,byte[]> attachment in attachmentContent)
{
MemoryStream m = new MemoryStream(attachment.Item2);
email.Attachments.Add(new System.Net.Mail.Attachment(m, attachment.Item1));
streams.add(m);
}
// client represents a System.Net.Mail.SmtpClient object
client.Send(email);
foreach(MemoryStream stream in streams)
{
stream.Dispose();
}
答案 2 :(得分:2)
是的,它是真的。退出块时使用语句关闭流。
请勿使用“ 使用”语句。发送电子邮件呼叫 dispose()方法以获取附件后。
...
...
msg.Send();
msg.Attachments.ToList().ForEach(x => x.ContentStream.Dispose());
对于 AlternateView ,您也可以使用相同的方式。
...
...
msg.AlternateViews.Add(alternateView);
...
msg.Send();
...
if (alternateView != null) {
mail.AlternateViews.Dispose();
}
答案 3 :(得分:0)
使用:
using (strMem = new MemoryStream((byte[])attDr["filedata"]))
{
using (strWriter = new StreamWriter(strMem))
{
strWriter.Flush(); strMem.Position = 0;
using (attachment = new Attachment(attDr["filename"].ToString()))
{
strMem.CopyTo(attachment.ContentStream);
msg.Attachments.Add(attachment);
}
}
}
答案 4 :(得分:-1)
将使用放在 MailMessage 上,它会在内部处理构成附件的流
using(var msg = new MailMessage())
{
...
...
var attachment = new Attachment(strMem, filename,contentType);
msg.Attachments.Add(attachment);
...
...
msg.Send();
}