DRobertE
DRobertE

Reputation: 3508

Disposing streams in called method from caller

I'm looking for a good way to dispose of a series of objects, so the problem is in GetMessage if I use a using statement for the underlying stream to create the attachment... in method 1 when I go to send the mail message the stream for the attachment is disposed of and will receive an error. If I take off the using statement it works find but I haven't disposed of DataStream Dest properly. My initial though was adding a parameter List to method one that I can add Dest to each time GetMessage is called and in method 1 at the end of the method loop through the list to dispose of the streams. SendMessage can be called in a loop from a batch process so many streams could potentially be created and I want to leave it to the caller (SendMessage) to dispose of them rather than in GetMessage since SendMessage is where the send takes place and I need to make sure the message has sent before disposal. Any suggestions???

                void sendMessage(MessageType type){
                   MailMessage m = Method2();
                   switch(type)
                   {
                      case type1:
                        m = Object1().GetMessage(param1)
                      case type2:
                        m = Object2().GetMessage(param1, param2)
                      case type3:
                        m = Object3().GetMessage(param1)
                      case type4:
                        m = Object4().GetMessage(param1, param2, param3)
                      case NewType5:
                        m = NewType5().GetMessage(param1, param2)
                   }
                   // this method does the send cause it has the mailmessage
                   m.Send();
                }

                class NewType5()
                {
                MailMessage GetMessage(){

                    // used to be 
                    // using (var Dest = new DataStream(true)){ .... }
                    DataStream Dest = new DataStream(true);

                    // code that reads info into the stream

                    // Go back to the start of the stream
                    Dest.Position = 0;

                    // Create attachment from the stream
                    Attachment mailattachement = new Attachment(Dest, contentType);

                    //Create our return value
                    var message = new MailMessage();
                    message.To.Add(UserInfo.UserDetail.Email);
                    message.Subject = "P&L Data View - " + DateTime.Now.ToString();
                    message.Attachments.Add(mailattachement);
                    return message;
               }
             }

To move send into GetMessage I would have to change all the other object implementations on all the other objects. I would rather let send message take care of the disposal for newtype5 because from a batch process it could be called 500 times. Does this make the example a little more clear. Send Message was already written an implemented against is several other objects with a GetMessage implementation. Mine just happens to use a stream and I can't dispose of the stream before the send takes place.

Upvotes: 0

Views: 388

Answers (2)

quetzalcoatl
quetzalcoatl

Reputation: 33506

Why not just move it to be a param of meth2: ?

            void method1(){
               using (var Dest = new DataStream(true))
               {
                   MailMessage m = Method2(Dest);
                   .....
                   m.Send();
               }
            }

            MailMessage Method2(Stream Dest){

                // code that reads info into the stream

                // Go back to the start of the stream
                Dest.Position = 0;

                // Create attachment from the stream
                Attachment mailattachement = new Attachment(Dest, contentType);

                //Create our return value
                var message = new MailMessage();
                message.To.Add(UserInfo.UserDetail.Email);
                message.Subject = "P&L Data View - " + DateTime.Now.ToString();
                message.Attachments.Add(mailattachement);
                return message;
           }

is your Message.Send() method asynchronous? do you want to parallelize the sending?

Upvotes: 1

Polyfun
Polyfun

Reputation: 9639

I suggest you do the MailMessage.Send in Method2; with the code you have given there does not seem to be any reason for doing it in the calling method.

Upvotes: 1

Related Questions