Error while trying to send mail from webapp

Hi,
I’m trying to put an email sending functionality into my webapp.
I implemented the functionality following the documentation, but I get an error in the MailSentHandler method, at the MailSemaphore.Release line.
The error is an IllegalLockingException and the error message is this: “Called Semaphore.Release too many times.”
What can be the cause? :thinking:

The error is telling you the exact problem. You are releasing the semaphore more than retaining it.

1 Like

It seems strange to me because I followed the instructions in the documentation…
I defined two public properties of the app (MailSemaphore As Semaphore and MailSocket As SMTPSecureSocket).

In the opening eventi of the app I have:

App.MailSemaphore = New Semaphore
App.MailSocket = New SMTPSecureSocket

AddHandler MailSocket.MailSent, AddressOf MailSentHandler
AddHandler MailSocket.ServerError, AddressOf MailServerErrorHandler

Then I have the two methods of the app object:

  1. MailSentHandler(m As SMTPSecureSocket)
  2. MailServerErrorHandler(m As SMTPSecureSocket, errorID As Integer, errorMessage As String, email As EmailMessage)

In each of them I have:

MailSemaphore.Release

Finally I have the SendMail(toAddress As String, subject As String, message As String) method in the pressed event of a button (only temporarily for testing purposes):

MailSemaphore.Signal

// Connect to Gmail
MailSocket.Address = "smtp.gmail.com"
MailSocket.Port = 465
MailSocket.ConnectionType = SMTPSecureSocket.TLSv1
MailSocket.SMTPConnectionMode = SMTPSecureSocket.ModeSSLTLS
MailSocket.Secure = True

MailSocket.Username = "myemail@gmail.com"
MailSocket.Password = "mypassword"

// Create EmailMessage
Var mail As New EmailMessage
mail.FromAddress = "myemail@gmail.com"
mail.AddRecipient(toAddress)
mail.Subject = subject
mail.BodyPlainText = message
mail.Headers.AppendHeader("X-Mailer","SMTP Test")

// Send it
MailSocket.Messages.AddRow(mail)
MailSocket.SendMail

Thus there is both the call to Signal and the call to Release, as reported in the documentation.
Am I missing something?

Yeah, so the problem you are most likely running into here are that the events associated with sockets all run on the main thread. Semaphores are meant to prevent different threads from accessing the same resource at the same time, but when those events fire, they all represent the main thread, and are trying to release the wrong semaphore.

If you’re truly only protecting a single resource, you should probably try using a CriticalSection instead. The docs for Semaphore say as much.

Regarding the issue you are trying to solve here… you don’t need locking for this. Just create an array to hold EmailMessage objects and every time you create one, add a message to the array and then call the method to send them. In the send method, use a static Boolean property to protect the method like this:

Static alreadySending as Boolean
If not alreadySending then
    AlreadySending = true
    While ubound(mailArray) > -1
        // send the first message
        MailArray.RemoveAt(0)
    Wend
    AlreadySending = false
End if

Semaphores and CriticalSections are overkill for what you are trying to do IMHO.

Something else you might want to consider… since sending email is a relatively time consuming process, putting that code into a helper console app will let you run it on a separate core and not block the thread at all.

How many emails do you want to send? Gmail probably restricts sending emails so that you can’t send too much spam.

Are the emails all the same? If the emails are all the same you could do a BCC.

2 Likes

I solved the problem. It was somehow related to using Gmail.
By changing the SMTP server to a different one, the code I reported in my previous post (which is the same as the example contained in the documentation) works perfectly!
Thanks anyway for your suggestions!