2011-08-19 4 views
5

は、私はちょうど私のデータベースの種類を服用してはMailMessageに変換しています。このコードコード解析が文句を言うと私はオブジェクトを処分していません。ここで何が間違っていますか?

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

考えてみましょう。 別の機能で送信されます。

コード解析では、正しい "msg"を削除していないことがわかります。しかし、私がここでそれをすれば、私はそれを送信しようとしているときに例外になります。

また、ここでのMemoryStreamを配置しないで文句:

msg.Attachments.Add(新アタッチメント(新しいのMemoryStream(attachment.Data)、 attachment.Name));

正しく処理する方法についてはわかりません。私は別のものを試してみましたが、基本的にはないはず「ストリームが閉じている」

答えて

2

言ってメールを送信するときに、例外を得ていた - 各ストリームを処分する各添付ファイル、を処分しますメールメッセージ後での処分します。また、リモーティングで使用されていないMemoryStreamを処分できないことは害ではありません。

この方法の警告を表示しないことをお勧めします。

EDIT:メッセージを表示しないように[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

"disposing" msg ""に関して、私が考えることができる唯一の方法は、MailMessageを返す代わりに、MailMessageへの参照を渡すことです。 このようなものです。それが良い考えであるかどうかは分かりません。

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

私は、ストリームが添付ファイルに保存され、後で読むだけであると思っています。 –

+0

@Jon Skeet、私はそれについて考えているので、ストリームは開いたままにする必要があります。 – Jethro

-1

使い捨てオブジェクトの作成者は、また、それを配置する必要があります。ここにメッセージを置くことができないなら、それは他のどこかの作成者から渡されるべきです。この場合、コード解析が正しく行われ、これらのメッセージを無視すると、非常に不幸なことに、漏れをデバッグするのが難しくなる可能性があります。

+0

所有権移転は非常に便利なコンセプトです。残念なことに、C#やコード分析のいずれもヘルプを提供していません。 –

+0

したがって、これは避けるべきです。したがって、作成者に使い捨てリソースを処分する責任を割り当てることが賢明です。 –

+0

作成者は必ずしも論理的所有者ではありません。たとえば、工場パターンでは、作成者は決して所有者ではなく、作成したリソースを工場で廃棄することもできません。代わりに、未割り当てのリソースが返される必要があります。 –

関連する問題