我在和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/

10-10 20:07