呼叫dispose()在对idisposable的引用中



我有一些代码可以在电子邮件中添加附件。我正在通过Attachment类构造函数的Stream超载添加它们。这样做的代码看起来像:

List<UploadedDocument> docs = DataBroker.GetUploadedDocs(Convert.ToInt32(HttpContext.Current.Session["offer_id"].ToString()));
//no need to keep this in session
HttpContext.Current.Session["offer_id"] = null;
int counter = 1;
foreach (UploadedDocument doc in docs)
{
    stream = new MemoryStream(doc.doc);
    attach = new Attachment(stream, "Attachment-" + counter.ToString());
    message.Attachments.Add(attach);              
}

其中doc.doc是字节数组。我想正确处理每个附件和流,但是在发送消息之前,我无法做到这一点,因此我正在考虑将它们添加到List<Attachment>List<Stream>中,然后迭代并拨打调用。

类似的东西:

List<Attachment> attachments;
List<Stream> streams;
//...
foreach(UploadedDocument doc in docs)
{
    stream = new MemoryStream(doc.doc);
    streams.Add(stream);
    attach = new Attachment(stream,"Name");
    attachments.Add(attach);
    message.Attachments.Add(attach);
}
//other processing
emailClient.Send(message);
if(attachments != null)
{
    foreach(Attachment attachment in attachments)
    {
        attachment.Dispose();
    }
}
if(streams != null)
{
    foreach(MemoryStream myStream in streams)
    {
        myStream.Dispose();
    }
}

但是,如果仍然有没有收集垃圾或其他内容的参考文献,但如果仍然有一个参考文献,则不会正确地将它们处置。有任何想法吗?

处理此操作的最简单方法就是在MailMessage上调用Dispose()

MailMessage.Dispose将自动处置所有附件,而这些附件又将关闭/ Dispose()所有基础流。

//other processing
emailClient.Send(message);
message.Dispose();  // Or just wrap this entire block in a using statement

这已经由mailmessage.dispose方法实现:

protected virtual void Dispose(bool disposing)
{
    if (disposing && !this.disposed)
    {
        this.disposed = true;
        if (this.views != null)
        {
            this.views.Dispose();
        }
        if (this.attachments != null)
        {
            this.attachments.Dispose();
        }
        if (this.bodyView != null)
        {
            this.bodyView.Dispose();
        }
    }
}

将MailMessage的用法包装到using语句中,并将MailMessage使用的所有资源发布在您离开using块之后发布:

using(var message = new MailMessage(from, to))
{
   foreach (UploadedDocument doc in docs)
   {
       stream = new MemoryStream(doc.doc);
       attach = new Attachment(stream, "Attachment-" + counter.ToString());
       message.Attachments.Add(attach);              
   }
   emailClient.Send(message);
}

已经有正确的回复(mailmessage.dispose),因此"如果仍然有参考,请正确处理它们...":

处置意志(也预期)在呼叫时释放资源,无论谁提及该对象。一种常见的方法之一是在对象中还具有内在标志,该旗帜实现了处置的处置,该标志将通过抛出"对象处置"例外。

,如果您在使用它们之前将流处置,则可以(并且可能已经这样做)观察此行为。IE。在您的邮件案例中,您可以尝试在message.Attachments.Add(attach);之后立即处置流,这很可能会导致Send拨打电话中的"流处置"例外。

请注意,在处置后有一些对象,例如内存中有特殊定义的行为。IE。MemoryStream屏蔽除了Toarray/Lenght/GetBuffer以外的所有调用,因为该类的主要目的之一是为您提供流的字节数组。作为副作用MemoryStreamDispose本质上只是设置标志来阻止其他呼叫(这很好,因为该类没有任何本机资源)。

相关内容

  • 没有找到相关文章

最新更新