C# 对IDisposable的引用调用dispose()
我有一些代码可以向电子邮件添加附件。我通过C# 对IDisposable的引用调用dispose(),c#,email,attachment,idisposable,C#,Email,Attachment,Idisposable,我有一些代码可以向电子邮件添加附件。我通过附件的类构造函数的流重载添加它们。执行此操作的代码如下所示: List<UploadedDocument> docs = DataBroker.GetUploadedDocs(Convert.ToInt32(HttpContext.Current.Session["offer_id"].ToString())); //no need to keep this in session HttpContext.Current.Session["of
附件的类构造函数的流
重载添加它们。执行此操作的代码如下所示:
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);
}
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();
}
}
但有些事情告诉我,如果仍然有一个引用未被收集或其他东西,那么它将无法正确地处理它们。有什么想法吗?处理这个问题最简单的方法就是在邮件中调用Dispose()
MailMessage.Dispose
将自动处理所有附件,然后关闭所有底层流
//other processing
emailClient.Send(message);
message.Dispose(); // Or just wrap this entire block in a using statement
处理此问题的最简单方法是在MailMessage
上调用Dispose()
MailMessage.Dispose
将自动处理所有附件,然后关闭所有底层流
//other processing
emailClient.Send(message);
message.Dispose(); // Or just wrap this entire block in a using statement
这已通过以下方法实现:
只需使用
语句将MailMessage的用法包装到中,在您使用
块离开后,将释放MailMessage使用的所有资源:
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的用法包装到中,在您使用
块离开后,将释放MailMessage使用的所有资源:
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),所以请“如果仍然有引用,请正确地处理它们…”:
Dispose将(也应该)在调用时释放资源,而不管谁引用了该对象。一种常见的方法是在实现Dispose的对象中也有内部标志,该标志将通过抛出“object Disposed”异常来阻止任何进一步的调用
如果在使用流之前处理流,您可以(可能已经)观察到这种行为。也就是说,在您的邮箱中,您可以尝试在message.Attachments.Add(attach)之后立即处理流
这很可能会在以后的Send
调用期间导致“流已处理”异常
请注意,有些对象(如MemoryStream)在Dispose之后具有专门定义的行为。也就是说,MemoryStream会阻止除ToArray/Lenght/GetBuffer之外的所有调用,因为此类的主要用途之一是为您提供流的结果字节数组。作为副作用,MemoryStream
的Dispose
本质上只是设置标志来阻止其他调用(这很好,因为此类没有任何本机资源)。已经有正确的回复(MailMessage.Dispose),所以“如果仍然有引用,请正确地处理它们…”
Dispose将(也应该)在调用时释放资源,而不管谁引用了该对象。一种常见的方法是在实现Dispose的对象中也有内部标志,该标志将通过抛出“object Disposed”异常来阻止任何进一步的调用
如果在使用流之前处理流,您可以(可能已经)观察到这种行为。也就是说,在您的邮箱中,您可以尝试在message.Attachments.Add(attach)之后立即处理流
这很可能会在以后的Send
调用期间导致“流已处理”异常
请注意,有些对象(如MemoryStream)在Dispose之后具有专门定义的行为。也就是说,MemoryStream会阻止除ToArray/Lenght/GetBuffer之外的所有调用,因为此类的主要用途之一是为您提供流的结果字节数组。作为副作用,MemoryStream
的Dispose
本质上只是设置标志来阻止其他调用(这很好,因为这个类没有任何本机资源)。应该考虑到这一点。我猜我只是不相信MailMessage
的Dispose()
会处理它的所有资源。多谢了,我早该想到的。我猜我只是不相信MailMessage
的Dispose()
会处理它的所有资源。非常感谢,谢谢!我应该想到这一点——只是不想盲目地相信MailMessage
的Dispose()
方法。我猜这就是文档的用途。但谁有时间呢汉克斯!我应该想到这一点——只是不想盲目地相信MailMessage
的Dispose()
方法。我猜这就是文档的用途。但谁有时间呢P