其他分享
首页 > 其他分享> > 在发送带有附件的电子邮件时,我是否应该处置MimeKit使用的流?

在发送带有附件的电子邮件时,我是否应该处置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(基本上是在使用)不会释放任何资源..但是会阻止对其进行读写.但是,如果将来将实现更改为另一种类型的Stream,事情可能会变得更加复杂.

我还深入研究了MikeKit的源代码,发现传递给AttachmentCollection.Add的Stream被“添加”到MemoryBlockStream中,该MemoryBlockStream继承自Stream(并实现Dispose),所以我假设它已经被处置了,但是在这一点上,我只是在猜.

有任何想法吗?

解决方法:

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

1-Overload需要byte []数据,您可以看到它们创建了一个流并保留了它的所有权.这是通过在using块上创建流来完成的.可以假定下游的代码(CreateAttachment())没有处理任何Stream处置.

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

我想说,在这种情况下,您最好自己处置.就是说,如果只能在流被消耗之后才能完成.

实际上,在调用Add之后,您的Stream已被使用.该方法返回后,所有数据将位于内存中,您可以处置流.您可以在LoadContent()上看到它.

就像您不想避免调用Dispose一样,因为您有一个MemoryStream知道可以在以后使用另一个需要Dispose的流.调用Add后处置Stream可能不是一个好主意.
万一库的行为在将来发生变化,并且在调用“添加您的流”时尚未消耗掉(我认为这是预期的行为).

仅在将数据写入NetworkSocket时才读取该流.实际上,在不将其全部加载到RAM的情况下流传输数据.

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

标签:mailkit,mimekit,stream,c
来源: https://codeday.me/bug/20191025/1932490.html