我在和Mailkit/Mimekit玩,有什么事困扰着我。我想用流发送带有附件的电子邮件。mimekit提供了BodyBuilder
类,使创建正文消息和附加文件变得非常容易:
public void SendEmail(string body, Stream attachment, string fileName)
{
var message = new MimeMessage();
message.From.Add(new MailboxAddress("Carl", "[email protected]"));
message.To.Add(new MailboxAddress("Rick", "[email protected]"));
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处理流吗?基本上(据我所知),消费者通常负责处理流。我也知道调用memoryStream上的dispose(我基本上正在使用)不会释放任何资源。但会阻止对它的读/写。但是,如果在将来,实现改变为另一种类型的流,事情会变得更复杂。
我还深入研究了mikekit源代码,发现传入
AttachmentCollection.Add
的流被“添加”到继承自stream(并实现dispose)的MemoryBlockStream
中,所以我假设它被disposed了,但在这一点上,我只是猜测。有什么想法吗?
最佳答案
通过检查mimekit上的代码。具体来说,这两个重载:
1-Overload这需要byte[] data
,您可以看到他们创建了一个流并保留它的所有权。这是通过在using block
上创建流来完成的。可以假设下游代码(CreateAttachment()
)没有处理任何流处理。
2-overload that you mention,流刚刚通过CreateAttachment()
。
在这种情况下,如果可以的话,你最好自己处理。也就是说,如果只有在流被消耗之后才能执行。
实际上,在调用Add
之后,您的流已被消耗。方法返回后,所有数据都将保留在内存中,您可以释放流。你可以在LoadContent()上看到这个。
就像您不想避免调用dispose一样,因为您有一个memoryStream,它知道以后可以使用另一个需要dispose的流。在调用Add
之后释放流可能是个坏主意。
如果库的行为在将来和调用Add
时发生了变化,那么您的流还没有被消耗(在我看来,这是预期的行为)。
只有在将数据写入networksocket时才会读取流。事实上是流式传输数据,而不是全部加载到ram中。
在这种情况下,您只能在调用Mailkit.Send
之后处理流。
关于c# - 发送带有附件的电子邮件时,应该处置MimeKit使用的流吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44486018/