Skip to main content
5 of 7
edited tags
RubberDuck
  • 30.9k
  • 6
  • 71
  • 174

Send Email just once

I want to send an email just once per day. There is one button and any user can click that button. So email must not be send 2 times. When first user click button then email is send and if some other user click button than email will not be send again.

This is how I implemented and it’s working. There are some cases, once a month, when 2 email are sent, but I don't know why.

I am sure that there is more elegant way to resolve this problem. Please share with me your ideas.

protected void Send(string email, String allRecipients, String subject, String body)
{
    //Be sure that email is send just once:
    //Lock an object, and if its already locked just continue,
    if (Monitor.TryEnter(syncLock))
    {
        try
        {
            //Send email only if is not send already.
            //Check in DB if is send.
            //IsSend function return true if email is send already, else false.
            if (!IsSent())
            {
                SendEmails(email, allRecipients, subject, body);
            }
        }
        finally
        {
            Monitor.Exit(syncLock);
        }
    }
}

Function that sends email:

public static void SendEmails(string email, String allRecipients, String subject, String body)
{
    //Flag if email is sent or not:
    Boolean isEmailSend = false;

    SmtpClient client = new SmtpClient();
    //Message:
    MailMessage message = new MailMessage(email, allRecipients, subject, body);
    try
    {
        isEmailSend = true;
        client.Send(message);

    }
    catch (SmtpException e)
    {
        isEmailSend = false;
        throw new SmtpException(e.ToString());
    }
    catch (TimeoutException e)
    {
        //Problem: Not sure if is email send or not:
        isEmailSend = false;
        throw new TimeoutException("TIME OUT:" + e.ToString());
    }
    catch (Exception e)
    {
        //Problem: Not sure if is email send or not:
        isEmailSend = false;
        throw new Exception(e.ToString());
    }
    finally
    {
        if (isEmailSend)
        {
            //Update DB.
            //Set that email is send.
            //This update in DB that email for current day is send already.
            SetAsSend();
        }
    }
}

Edit: IsSent function

    //Check if meeting is sent today.
    public static bool IsSent()
    {
        string connectionString = ConfigurationManager.ConnectionStrings["connectionString"].ConnectionString;
        bool isSent = false;

        const string CHECK_IF_SEND = "SELECT TOP 1 IsSent FROM MessageTable m WHERE m.date =@todayDate ";

        SqlConnection conn = new SqlConnection(connectionString);
        SqlCommand command = new SqlCommand(CHECK_IF_SEND, conn);
        command.Parameters.Add("@todayDate", DbType.Date).Value = DateTime.Today;

        try
        {
            conn.Open();
            Object result = command.ExecuteScalar();
            if (result != null)
            {
                isSent = (bool)result;
            }
        }
        finally
        {
            conn.Close();
            conn.Dispose();
        }
        return isSent;
    }
Raskolnikov
  • 812
  • 2
  • 11
  • 25