Udostępnij za pośrednictwem


Using CDOSYS from .Net?! Be Careful with Attachments!

First off there is no justification why you should be using Cdosys directly, you should use System.Web.Mail if you are still on .Net 1.1 otherwise you should upgrade to System.Net.Mail.

Anyways, the problem I want to mention is when you use CDOSYS.dll directly from .Net 1.1 or 2.0 or even 3.5, the problem is with memory management.

Take this sample code..

 Function SendMail()
        Dim iMsg As New CDO.Message
        With iMsg
            .To = "test@server.com"
            .From = "test@server.com"
            .Subject = "Hello, This is a test mail !"
            .HTMLBody = "<b>Hi</b>, <i>This is a test <u>HTML</u> mail !</i>"
            .AddAttachment("d:\attachment.txt")
        End With
        iMsg = Nothing
End Function

Looks short and sweet like there is nothing wrong with this, think again!

This code is holding the reference to File Handle and not going to release it even after you set iMsg = Nothing

The solution here is to release the COM Object (CDOSYS) properly by calling GC.Collect() followed by GC.WaitForPendingFinalizers() but outside of this code block.

Now consider this sample…

 Function SafeSendMail()
        SendMail()
        Gc.Collect()
        GC.WaitForPendingFinalizers()
End Function

Function SendMail()
        Dim iMsg As New CDO.Message
        With iMsg
            .To = "test@server.com"
            .From = "test@server.com"
            .Subject = "Hello, This is a test mail !"
            .HTMLBody = "<b>Hi</b>, <i>This is a test <u>HTML</u> mail !</i>"
            .AddAttachment("d:\attachment.txt")
        End With
        iMsg = Nothing
End Function

This will make sure that the CDOSYS is collected as soon as you leave the SendMail block otherwise you won’t be able to access the file for writing/deleting it.

Happy Debugging!!!