我正在玩MailKit / MimeKit,有些东西让我烦恼。我想使用流发送带附件的电子邮件。 MimeKit提供了BodyBuilder
类,这使得创建正文消息和附加文件变得非常容易:
public void SendEmail(string body, Stream attachment, string fileName)
{
var message = new MimeMessage();
message.From.Add(new MailboxAddress("Carl", "carl@site.com"));
message.To.Add(new MailboxAddress("Rick", "rick@site.com"));
message.Subject = "Things got messy...?";
var builder = new BodyBuilder();
builder.TextBody = body;
builder.Attachments.Add(fileName, attachment);
message.Body = builder.ToMessageBody();
using (var client = new SmtpClient())
{
// code to send e-mail here...
}
}
我在代码中的其他地方生成了流,但我没有关闭它,所以我可以将它传递给MimeKit。不明确的是:MimeKit是否处理了流?基本上(据我所知),消费者通常负责处理Streams。我也知道在MemoryStream上调用dispose(我基本上使用它)不会释放任何资源......但是会阻止读取/写入它。但是,如果将来实现更改为另一种类型的流,事情会变得更加复杂。
我还深入研究了MikeKit的源代码,发现传入AttachmentCollection.Add
的Stream已被添加到#39;进入一个继承自Stream的MemoryBlockStream
(并实现Dispose),所以我想它会被处理掉,但此时我只是在猜测。
有什么想法吗?
答案 0 :(得分:2)
您无需处置这些流。如果你愿意,你可以,但没有必要。
答案 1 :(得分:2)
通过检查MimeKit上的代码。特别是两个重载:
1 - Overload,byte[] data
,你可以看到他们创建了一个流并保留了它的所有权。这是通过在using block
上创建流来完成的。可以假设下游代码(CreateAttachment()
)没有处理任何Stream dispose。
2 - overload that you mention,流刚刚传递到CreateAttachment()
。
我会说在这种情况下你最好自己处理它,如果可以的话。也就是说,如果只在流消耗完后才能完成。
事实上,在致电Add
后,您的Stream已被使用。方法返回后,所有数据都将存储在内存中,您可以处理流。您可以在LoadContent()上看到这一点。
就像你不想避免调用Dispose一样,因为你知道有一个MemoryStream可以在以后使用另一个需要Dispose的流。在致电Add
后处理您的信息流可能是一个坏主意。
如果库的行为在将来发生变化,并且在调用Add
时您的流尚未消耗(在我看来这将是预期的行为)。
只有在将数据写入NetworkSocket时才会读取流。实际上是流数据,而不是将它全部加载到RAM中。
在这种情况下,您只能在调用Mailkit.Send
后处理流。