Delayed send with smtpclient in .net 2.0

Is there any way to force the smtpclient to send mail immediately with the .send method in system.net.mail 2.0 Right now it takes anywhere from 90 secods to two minutes before the mail is actually sent once the .send method executes. I've tried setting the object to nothing immediately after the .send method call, but no luck.

The real issue for me is the send delay is also causing the smtpclient  to hold a lock on attached files that are being sent for that same 90 seconds to two minutes. I need to move the file immediately after emailing it, and right I get an exception telling me two processes can't access the file at the same time - obviously the smtpclient holding onto the file until it's ready to sent it. BTW, this app was using  system.web.mail with none of these issues - I'm trying to upgrade it to 2.0.

Thanks,

Geoff


Answer this question

Delayed send with smtpclient in .net 2.0

  • JudyX

    Could you add some code snippets on how you use SmtpClient   Also, could you enable trace logging and send it to me   What type of SMTP server are you sending e-mail through   What speed connection are you on   I would like to understand more about your environment so that I can try to help you figure out what is going on.

    See http://blogs.msdn.com/dgorti/archive/2005/09/18/471003.aspx for information on enabling trace logging. 

  • daw

    Thanks for the config. Very interesting results. Here's the tail of the log file, after the last part of message is sent.. Take a look at the last two entires, especially the timestamps. The mail conversation with the exchange server doesn't appear to end with the normal smtp "quit" command, and until the socket dispose you see in the log, the mail doesn't get delivered. It's almost as if .net wants to pool the connection and keep it open in case there's more mail to send. So now that I see the behavior, how do I change it Some magical setting in a config file somewhere

    Thanks,

    Geoff

    ... System.Net.Sockets Verbose: 0 : [3460] Socket#13951800::Send()
        DateTime=2005-12-12T21:16:11.3153184Z
    System.Net.Sockets Verbose: 0 : [3460] Data from Socket#13951800::Send
        DateTime=2005-12-12T21:16:11.3309431Z
    System.Net.Sockets Verbose: 0 : [3460] 00000000 : 0D 0A 2D 2D 2D 2D 62 6F-75 6E 64 61 72 79 5F 30 : ..----boundary_0
        DateTime=2005-12-12T21:16:11.3778172Z
    System.Net.Sockets Verbose: 0 : [3460] 00000010 : 5F 65 32 62 30 33 31 31-31 2D 30 65 36 30 2D 34 : _e2b03111-0e60-4
        DateTime=2005-12-12T21:16:11.3934419Z
    System.Net.Sockets Verbose: 0 : [3460] 00000020 : 39 35 35 2D 38 32 37 64-2D 32 34 65 38 36 38 39 : 955-827d-24e8689
        DateTime=2005-12-12T21:16:11.4246913Z
    System.Net.Sockets Verbose: 0 : [3460] 00000030 : 65 35 32 38 39 2D 2D 0D-0A                      : e5289--..
        DateTime=2005-12-12T21:16:11.4403160Z
    System.Net.Sockets Verbose: 0 : [3460] Exiting Socket#13951800::Send()     -> 57#57
        DateTime=2005-12-12T21:16:11.4559407Z
    System.Net.Sockets Verbose: 0 : [3460] Socket#13951800::Send()
        DateTime=2005-12-12T21:16:11.4715654Z
    System.Net.Sockets Verbose: 0 : [3460] Data from Socket#13951800::Send
        DateTime=2005-12-12T21:16:11.4871901Z
    System.Net.Sockets Verbose: 0 : [3460] 00000000 : 0D 0A                                           : ..
        DateTime=2005-12-12T21:16:11.5028148Z
    System.Net.Sockets Verbose: 0 : [3460] Exiting Socket#13951800::Send()     -> 2#2
        DateTime=2005-12-12T21:16:11.5184395Z
    System.Net.Sockets Verbose: 0 : [3460] Socket#13951800::Send()
        DateTime=2005-12-12T21:16:11.5340642Z
    System.Net.Sockets Verbose: 0 : [3460] Data from Socket#13951800::Send
        DateTime=2005-12-12T21:16:11.5496889Z
    System.Net.Sockets Verbose: 0 : [3460] 00000000 : 0D 0A 2E 0D 0A                                  : .....
        DateTime=2005-12-12T21:16:11.5653136Z
    System.Net.Sockets Verbose: 0 : [3460] Exiting Socket#13951800::Send()     -> 5#5
        DateTime=2005-12-12T21:16:11.5965630Z
    System.Net.Sockets Verbose: 0 : [3460] Socket#13951800::Receive()
        DateTime=2005-12-12T21:16:11.6121877Z
    System.Net.Sockets Verbose: 0 : [3460] Data from Socket#13951800::Receive
        DateTime=2005-12-12T21:16:11.6278124Z
    System.Net.Sockets Verbose: 0 : [3460] 00000000 : 32 35 30 20 4D 61 69 6C-20 71 75 65 75 65 64 20 : 250 Mail queued
        DateTime=2005-12-12T21:16:11.6434371Z
    System.Net.Sockets Verbose: 0 : [3460] 00000010 : 66 6F 72 20 64 65 6C 69-76 65 72 79 2E 0D 0A    : for delivery...
        DateTime=2005-12-12T21:16:11.6590618Z
    System.Net.Sockets Verbose: 0 : [3460] Exiting Socket#13951800::Receive()     -> 31#31
        DateTime=2005-12-12T21:16:11.6746865Z
    System.Net Verbose: 0 : [3460] Exiting SmtpClient#66753006::Send()
        DateTime=2005-12-12T21:16:11.6903112Z
    System.Net.Sockets Verbose: 0 : [5636] Socket#13951800::Dispose()
        DateTime=2005-12-12T21:17:44.7978985Z


  • city_ash

    Ok, I found the problem with the file handle not being released.  Turns out that disposing either the MailMessage object or the Attachment object frees up the stream that is holding onto the file (which makes sense, but I am not sure why calling GC.Collect didn't result in this problem going away). 

    Please give it a try and let me know what you find.

  • Bernardo Heynemann

    What if you put the following code right after you call Send()   Note that this is not recommended for your application except for debugging purposes.



    GC.Collect();
    GC.WaitForPendingFinalizers();

     


  • rkocur

    No, I didn't get the delayed send problem in house.  Can you e-mail me the entire trace log  

    Also, can you work on getting a network sniff for me   See this blog for information on netmon usage.  Please e-mail it to me when you have it.

  • MADCookie

    Disposing the Attachment ojbect fixes the file handle issue, thanks!

    I take it you were also able to repro the delayed sending, and that's something you're still looking into

    BTW, tracing is sweet.What a great addition to the framework. Big Smile

    Thanks,

    Geoff

  • WolfKC

     gm001 wrote:
    The mail is not leaving my machine during the delay, and I can force the mail to be sent immediately by stopping the debug session.


    Can you explain this a little more   What do you mean by "stopping the debug session"   Are you broken into a debugger or just have a debugger attached   What happens if you don't have a debugger attached Do you still get the delay

  • William Choong

    I have created an in-house repro of this problem.  Let me investigate and I will let you know what I find.

  • N Anderton

    Were you able to get a trace log of the problem   Here is the app.exe.config file I would use:



    < xml version="1.0" encoding="UTF-8" >

    <configuration>
        <system.diagnostics>
      <trace autoflush="true" />
                    <sources>
                    <source name="System.Net">
                            <listeners>
                                <add name="System.Net"/>
                            </listeners>
                    </source>
                      <source name="System.Net.Sockets">
                            <listeners>
                                <add name="System.Net"/>
                            </listeners>
                    </source>
                      </sources>
            <sharedListeners>
                    <add
                      name="System.Net"
                      type="System.Diagnostics.TextWriterTraceListener"
                      initializeData="System.Net.trace.log"
                      traceOutputOptions = "DateTime"
                    />
            </sharedListeners>
     <switches>
                    <add name="System.Net" value="Verbose" />
                    <add name="System.Net.Sockets" value="Verbose" />                
     </switches>
     </system.diagnostics>
    </configuration>


     




    Also, just as a note, you should make sure that you scan that trace log and make sure any private information is removed before posting it.



  • Andrej Lindic

    Sorry guys, I really didn't provide enough info on my environment.

    I'm sending mail to an Exchange server on my local network, so it's a 100Mb link straight to an internal Exchange server. The mail is not leaving my machine during the delay, and I can force the mail to be sent immediately by stopping the debug session. Below is the code that's generating and sending the mail.

    I need to move the attached file immediately after sending the mail, and because of the delay I'm getting an execption on the file.move at the end as the smtpclient still has a lock on the file.

    Geoff

           

    ' Send the message

            Me.Cursor = Cursors.WaitCursor
            ' send the message using the data in the UI controls for the envelope metadata
            ' so the user can change destination address, subject, etc.
            Try
                Dim oFromAddr As New System.Net.Mail.MailAddress("xxxxx@yyyyy.com", "Mail Forwarding Service")
                Dim oToAddr As New System.Net.Mail.MailAddress(Me.txtTo.Text)
                Dim mailMsg As New MailMessage(oFromAddr, oToAddr)
                Dim oAttach As New Attachment(oMessage.Filename, "message/rfc822")
                oAttach.Name = oMessage.Subject

                mailMsg.Subject = Me.txtSubject.Text
                mailMsg.Body = Me.rtbReason.Text
                mailMsg.Attachments.Add(oAttach)

                Try
                    Dim osmtpClient As New SmtpClient
                    osmtpClient.Host = "mail1.xxxxxx.com"
                    osmtpClient.Send(mailMsg)
                    ' close everything to release mail
                    oAttach = Nothing
                    mailMsg = Nothing
                    osmtpClient = Nothing
                Catch ex As Exception
                    MessageBox.Show("Sending Failed... Check the To: Address", Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Error)
                  End Try
            Catch
                MessageBox.Show("Error Creating Mail Message", Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Error)
                Exit Sub
            End Try


            ' move the attachment file to the finished directory
            Try
                Dim sDest As String = ""
                sDest = Regex.Replace(oMessage.Filename, "(Header|Keyword|RBL|URI|Harvesting|Bayesian|Deferred)", "Finished", RegexOptions.Compiled Or RegexOptions.IgnoreCase)
                File.Move(oMessage.Filename, sDest)
            Catch
                MessageBox.Show("Error moving sent message file.", Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Error)
            End Try

     



  • mark_W

    What I meant was that if I run the app in VS with no breakpoints and perform an action that causes a message to be sent, I get the delay. If I stop the app during the delay period the mail is immediately sent as the app closes. Same thing holds true if I run the .exe outside of VS. Seems like it needs the GC to run before it will send the message.

    Geoff

  • Lognath1

    No joy. Still waits for the same amount of time or until I close the app. Guess that kills the GC theory.

    Geoff

  • Brian S. Ward

    Great, thanks.

    Geoff

  • Syran

    That said, SMTP is unlike real time (depending on your interpretation) protocol like
    HTTP and FTP. SMTP is a store and forward protocol. It may take any amount of time. Usually we are used to speedy links and hence your email may appear instantaneous - but it can take an arbitrary time.
    What is more important to know - is if the mail is leaving your machine. That you can easily infer by tracing using the blog entry jon has pointed out. Or Just use a regular network monitor

    Thanks


  • Delayed send with smtpclient in .net 2.0