2011-08-19 36 views
5

考慮以下代碼代碼分析抱怨我沒有處理對象。這裏有什麼問題?

private MailMessage GetMailMessageFromMailItem(Data.SystemX.MailItem mailItem) 
     { 

      var msg = new MailMessage(); 

      foreach (var recipient in mailItem.MailRecipients) 
      { 
       var recipientX = Membership.GetUser(recipient.UserKey); 
       if (recipientX == null) 
       { 
        continue; 
       } 

       msg.To.Add(new MailAddress(recipientX.Email, recipientX.UserName)); 
      } 

      msg.From = new MailAddress(ConfigurationManager.AppSettings["EmailSender"], 
            ConfigurationManager.AppSettings["EmailSenderName"]); 

      msg.Subject = sender.UserName; 
      if (!string.IsNullOrEmpty(alias)) msg.Subject += "(" + alias + ")"; 
      msg.Subject += " " + mailItem.Subject; 
      msg.Body = mailItem.Body; 
      msg.Body += Environment.NewLine + Environment.NewLine + "To reply via Web click link below:" + Environment.NewLine; 
      msg.Body += ConfigurationManager.AppSettings["MailPagePath"] + "?AID=" + ContextManager.AccountId + "&RUN=" + sender.UserName; 

      if (mailItem.MailAttachments != null) 
      { 
       foreach (var attachment in mailItem.MailAttachments) 
       { 
        msg.Attachments.Add(new Attachment(new MemoryStream(attachment.Data), attachment.Name)); 
       } 
      } 

      return msg; 
     } 

我只是把我的數據庫類型,並轉換爲MAILMESSAGE。 它被髮送到另一個函數。

代碼分析告訴我,我沒有處置「msg」,這是正確的。但是,如果我在這裏做 - 我試圖發送它時發生異常。

此外,它抱怨這裏沒有處置的MemoryStream:

msg.Attachments.Add(新附件(新的MemoryStream(attachment.Data), attachment.Name));

我不知道如何妥善處置它。我嘗試了不同的東西,但發送郵件時說「流關閉」時出現異常

回答

2

基本上你不應該 - 處理郵件消息後面將處置每個附件,這將處置每個流。此外,未處理未用於遠程處理的MemoryStream不會造成任何傷害。

我建議你抑制這種方法的警告。

編輯:我懷疑你可以使用[SuppressMessage]壓制消息。


注意,有一些代碼將拋出代碼中途的方法,所以你最終永遠無法處理消息的,即使你有在調用代碼using陳述的風險。如果你真的很困擾,你可以寫:

private MailMessage GetMailMessageFromMailItem(Data.SystemX.MailItem mailItem) 
{ 
    bool success = false; 
    var msg = new MailMessage(); 
    try 
    { 
     // Code to build up bits of the message 
     success = true; 
     return msg; 
    } 
    finally 
    { 
     if (!success) 
     { 
      msg.Dispose(); 
     } 
    } 
} 

我個人認爲這是過度殺傷。

+0

如何禁止警告? – katit

+0

@katit:通過 - 我不使用代碼分析。我確信網上有很多說明。 –

+0

@Downvoter:照顧評論? –

0

關於「不處置」msg「」,我能想到的唯一方法是,而不是返回MailMessage,而是傳入對MailMessage的引用。 就是這樣。不知道這是一個好主意。

private void GetMailMessageFromMailItem(ref MailMessage msg, Data.SystemX.MailItem mailItem) 
+0

我懷疑這個流將被存儲在附件中,並且只能在稍後閱讀。 –

+0

@Jon Skeet,現在我想到了,這條流將需要保持開放。 – Jethro

-1

一次性物體的創造者也應該處置它。如果你不能在這裏處理消息,那麼它應該從其他地方的創建者傳入。在這種情況下,代碼分析是正確的,如果您忽略這些消息,最終可能會導致非常不幸和難以調試的泄漏。

+0

所有權轉讓是一個非常有用的概念,不幸的是C#和代碼分析都沒有提供幫助。 –

+0

因此應該避免。因此,分配創建者負責處理其可支配資源是明智的。 –

+0

創作者並不總是合乎邏輯的所有者。例如,在工廠模式中,創建者永遠不是所有者,工廠也不能處理它創建的資源。相反,必須返回未處理的資源。 –