2011-08-19 10 views
5

rozważyć ten kodAnaliza kodu narzeka, że ​​nie wyrzucam przedmiotów. Co jest nie tak?

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; 
     } 

prostu biorę mój typ bazy danych i konwersji na MailMessage. To jest wysłane w innej funkcji.

Analiza kodu mówi, że nie wyrzucam "msg", co jest poprawne. Ale jeśli zrobię to tutaj - otrzymuję wyjątek, kiedy próbuję go wysłać.

Ponadto, narzeka i nie wyrzucaj MemoryStream tutaj:

msg.Attachments.Add (nowy załącznik (new MemoryStream (attachment.Data) attachment.Name));

Nie mam pojęcia, jak prawidłowo go usunąć. Próbowałem różnych rzeczy, ale był coraz wyjątki podczas wysyłania poczty mówiąc: „Stream zamyka”

Odpowiedz

2

Zasadniczo nie należy - usuwania wiadomości e-mail później będzie wyrzucać każdego załącznika, która będzie dysponować każdego strumienia. Poza tym nieudana próba pozbycia się numeru MemoryStream, który nie jest używany do zdalnego dostępu, nie wyrządzi szkody.

Proponuję wyłączyć ostrzeżenie dla tej metody.

EDYTOWANIE: Podejrzewam, że można użyć [SuppressMessage], aby wyłączyć komunikat.


Należy pamiętać, że istnieje ryzyko, że niektóre kod wygeneruje kod półmetku tej metody, więc w końcu nie mogąc pozbyć się komunikatu nawet jeśli masz using oświadczenie w kodzie wywołującym. Jeśli naprawdę się o to martwisz, możesz napisać:

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(); 
     } 
    } 
} 

Osobiście mogę powiedzieć, że to przesada.

+0

Jak ukryć ostrzeżenia? – katit

+0

@katit: Pomiń - nie używam analizy kodu. Jestem pewien, że w Internecie jest mnóstwo instrukcji. –

+0

@Dvvoter: Chcesz się skomentować? –

0

Jeśli chodzi o "nie wyrzucać" msg "", jedyny sposób, jaki mogę wymyślić, to zamiast zwracać MailMessage, a raczej przekazać odwołanie do MailMessage. Coś takiego. Nie jestem pewien, czy to taki dobry pomysł.

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

Podejrzewam, że strumień będzie przechowywany w załączniku i będzie czytany później. –

+0

@Jon Skeet, teraz, kiedy o tym myślę, strumień musiał pozostać otwarty. – Jethro

-1

Twórca obiektu jednorazowego użytku również powinien go wyrzucić. Jeśli nie możesz przekazać wiadomości tutaj, to powinna ona zostać przekazana przez innego twórcę. Analiza kodu jest w tym przypadku właściwa, a jeśli zignorujesz te wiadomości, możesz otrzymać bardzo niefortunne i trudne do usunięcia błędy.

+0

Przekazanie własności to bardzo przydatna koncepcja, której niestety pomoc ani C#, ani analiza kodu nie stanowią pomocy. –

+0

Dlatego należy tego unikać. Dlatego mądrze jest przypisać odpowiedzialność twórcy za pozbycie się jego zasobów jednorazowych. –

+0

Twórca nie zawsze jest właścicielem logicznym. Na przykład w fabrycznym wzorze twórca nigdy nie jest właścicielem, ani też fabryka nie może rozporządzać zasobem, który tworzy. Zamiast tego należy zwrócić niewykorzystany zasób. –