摘要:[C#]使用MailMessage後無法刪除附件
情況:在使用Attachment附加某一檔案後,寄信後想要刪除該檔案卻沒有刪除,
手動去刪除也會出現有其他程式正在使用,出現資源被咬住的狀況。
原因:在附加檔案後,Attachment就算在寄出後仍會咬住io串流,讓檔案無法當下被刪除。
Solution:需要對MailMessage使用Dispose方法,釋放所咬住的資源。
MailMessage msg = new MailMessage("test@gmail.com", "test@gmail.com.tw", "subject", "content");
msg.Attachments.Add(new Attachment(@"C:\test.txt"));
SmtpClient smtp = new SmtpClient("smtp.gmail.com", 25);
smtp.Credentials = new NetworkCredential("test", "test");
smtp.EnableSsl = true;
smtp.Send(msg);
File.Delete(@"C:\test.txt"); //到該路徑下會發現該檔案仍在沒有刪除。
但若是在File.Delete前面加上msg.Dispose(); 就可以順利刪除了。
這時後來看原始碼的部份:
Step1:呼叫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();
}
}
}
//我們會發現Attachment並沒有Dispose方法,所以它會直接使用母類別,
//也就是AttachmentBase的Dispose方法。
Step2:呼叫AttachmentBase的Dispose
protected virtual void Dispose(bool disposing)
{
if (disposing && !this.disposed)
{
this.disposed = true;
//part型別為 MimePart 類別,為AttachmentBase的屬性
this.part.Dispose();
}
}
Step3:呼叫MimePart的Dispose,關閉io串流
public void Dispose()
{
if (this.stream != null)
{
this.stream.Close();
}
}