Search code examples
vb.netsendmailsmtpclient

How SendSync deals with thread pool


Question1:

I'm sending message using SendAsync:

https://learn.microsoft.com/en-us/dotnet/api/system.net.mail.smtpclient.sendasync?view=netframework-4.7.2

I'm sending massive emails and I'm getting too much delay in the message callback: client.SendCompleted

The email is sent async but the callback appear to be serial, it appears there is only one thread sending and receiveing the emails.

e.g. If a message callback delays 1 second to be back from the mail servers, and I send 20 emails it will delay about 20 seconds to all messages to be delivered and completed.

So it appears there's just one thread sending the messages in a sequencial queue...

If SendAsync internally deals with thread pool is there a way to change the number of threads in this pool, max num threads an other things related to thread pools?

Question2:

Another related question about SendMailAsync: https://learn.microsoft.com/en-us/dotnet/api/system.net.mail.smtpclient.sendmailasync?view=netframework-4.7.2

Internally, SendMailAsync does the same thing of SendAsync, despite the fact the code design is a little different?

What's the real difference between SendAsync to SendMailAsync; should it solve the problem I'm relating in the quesiton 1?

THE CODE

Dim counter = 0

Public Async Function SendEmail(email As String, bodystuff As String) As Task
    Dim smtp As New SmtpClient() '"email-smtp.us-west-3.amazonaws.com")
    Dim hostloginpass = "email-smtp.us-west-3.amazonaws.com, AKDKJDAKJ2SKJMSDKJ2,AK2KD298;kdj2kjdkjaiuwkmp2KKK2098K2la97ksjNW,Test_Site"
    smtp.Host = cla_util.sGetToken(hostloginpass, 1, ",")
    smtp.Port = 587
    smtp.Credentials = New System.Net.NetworkCredential(getTokenFromArr(hostloginpass, 2, ","), getTokenFromArr(hostloginpass, 3, ","))
    smtp.EnableSsl = true

    Dim from As New MailAddress("[email protected]", "Info", System.Text.Encoding.UTF8)
    Dim [to] As New MailAddress(email)
    Dim message As New MailMessage(from, [to])
    message.Body = String.Format("The message I want to send is to this <b>contact: {0}{1}</b>", vbCrLf, bodystuff)
    message.IsBodyHtml = True
    message.BodyEncoding = System.Text.Encoding.UTF8
    message.Subject = "Test email subject"
    message.SubjectEncoding = System.Text.Encoding.UTF8


    'commented -> Await smtp.SendMailAsync(message)
    smtp.SendMailAsync(message)

    counter = counter + 1

    System.Console.WriteLine("Counter -> " & counter)
End Function

Dim _isCompleted
Dim _timing

Dim Tasks As New ArrayList

Public Async Sub StartEmailRun()
    Try
        Dim sWatch As New Stopwatch()

        sWatch.Start()

        For i = 0 To 50
            Tasks.Add(SendEmail("[email protected]", "email test"))
        Next

        Console.WriteLine("SETP OUT OF THE SENDING")

        _isCompleted = True

        sWatch.Stop()
        _timing = sWatch.ElapsedMilliseconds

    Catch ex As Exception
        MsgBox(ex.ToString)
    End Try
End Sub

Public Async Sub StartEmailRun2()
    Try
        Dim sWatch As New Stopwatch()

        sWatch.Start()

For i = 0 To 50
    Dim thread as New Thread(
      Sub() 
        SendEmail("[email protected]", "email test")
      End Sub
    )
    thread.Start()
Next

        Console.WriteLine("SETP OUT OF THE SENDING")

        _isCompleted = True

        sWatch.Stop()
        _timing = sWatch.ElapsedMilliseconds

    Catch ex As Exception
        MsgBox(ex.ToString)
    End Try
End Sub

Solution

  • The problem I think is that SmtpClient is obsolete:

    https://learn.microsoft.com/pt-br/dotnet/api/system.net.mail.smtpclient?view=netframework-4.7.2

    "SmtpClient doesn't support many modern protocols. It is compat-only. It's great for one off emails from tools, but doesn't scale to modern requirements of the protocol."

    "Use MailKit or other libraries."