使用MailMessage後無法刪除附件

  • 1917
  • 0
  • C#
  • 2013-06-15

摘要:[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();
			}
}