在发送带附件的电子邮件时,我应该处理MimeKit使用的流吗?

时间:2017-06-11 16:18:30

标签: c# stream mailkit mimekit

我正在玩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),所以我想它会被处理掉,但此时我只是在猜测。

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

您无需处置这些流。如果你愿意,你可以,但没有必要。

答案 1 :(得分:2)

通过检查MimeKit上的代码。特别是两个重载:

1 - Overloadbyte[] data,你可以看到他们创建了一个流并保留了它的所有权。这是通过在using block上创建流来完成的。可以假设下游代码(CreateAttachment())没有处理任何Stream dispose。

2 - overload that you mention,流刚刚传递到CreateAttachment()

我会说在这种情况下你最好自己处理它,如果可以的话。也就是说,如果只在流消耗完后才能完成。

事实上,在致电Add后,您的Stream已被使用。方法返回后,所有数据都将存储在内存中,您可以处理流。您可以在LoadContent()上看到这一点。

就像你不想避免调用Dispose一样,因为你知道有一个MemoryStream可以在以后使用另一个需要Dispose的流。在致电Add后处理您的信息流可能是一个坏主意。 如果库的行为在将来发生变化,并且在调用Add时您的流尚未消耗(在我看来这将是预期的行为)。

只有在将数据写入NetworkSocket时才会读取流。实际上是流数据,而不是将它全部加载到RAM中。

在这种情况下,您只能在调用Mailkit.Send后处理流。