C# 我是否应该处理MimeKit在发送带有附件的电子邮件时使用的流?

C# 我是否应该处理MimeKit在发送带有附件的电子邮件时使用的流?,c#,stream,mailkit,mimekit,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@sit

我在玩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是否处理流?基本上(据我所知),用户通常负责处理流。我也知道在MemoryStream上调用dispose(我基本上正在使用)不会释放任何资源。。但会阻止对其进行读/写操作。但是,如果将来实现更改为另一种类型的流,事情可能会变得更加复杂

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


有什么想法吗?

您不需要处理这些流。如果需要,您可以这样做,但这不是必需的。

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

1-这需要
字节[]数据
,您可以看到它们创建了一个流并保留其所有权。这是通过使用block在
上创建流来完成的。可以假设下游代码(
CreateAttachment()
)没有处理任何流

2-流刚刚传递到
CreateAttachment()

我想说,在这种情况下,如果可以的话,你最好自己处理。也就是说,如果只能在流被消耗后执行此操作

事实上,在调用
Add
之后,您的流已经被消耗。一旦方法返回,所有数据都将存储在内存中,您可以处理流。你可以在电视上看到这个

正如您不想避免调用Dispose,因为您有一个MemoryStream,知道以后可能会使用另一个需要Dispose的流。调用
Add
后处理流可能是个坏主意。 如果库的行为在将来发生变化,并且在调用
Add
时,您的流尚未被使用(我认为这是预期的行为)

仅在将数据写入NetworkSocket时读取流。事实上,流式传输数据,而无需将其全部加载到RAM中


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

您能解释一下这种情况的原因吗?
MimeKit
是为您这样做的吗?这个问题让我回想起
HttpClient
场景,在该场景中,我们(好吧,我们开发人员的一堆又一堆)拒绝处理该类,因为它继承了
IDispose
,但在2016年,我们被告知要将其保留为单例,不要处理(并通过代码示例解释了原因)。所以-只是想学:)这正是我的观点。我知道答案,所以人们可以说我根本不需要这个问题。。但是我想知道它是如何工作的,这样我就不会盲目地做事情了。仅当类使用非托管资源时才需要Dispose方法。