Sending SMTP email Asynchronously with multiple Retry in case of failure.

Sadalkar, Rajesh 1 Reputation point
2021-11-17T10:46:06.597+00:00

Hello ,

I am sending SMTP emails Asynchronously using below mentioned code in ASP.net MVC Application.
Unable to catch exception and retry same message until we send message successfully.
Can any one suggest method how to catch async exception in caller and retry the send a message again until it send successfuly.

    public static void SendEmail(System.Net.Mail.MailMessage m)
    {

        try
        {
            System.Net.Mail.SmtpClient smtpClient = null;
            smtpClient = new System.Net.Mail.SmtpClient(Utils.SystemAppSettings("Application_SMTPServer"));

    log.Debug("SendEmail with Async started -" + m.To.ToString());


                SendEmailDelegate sd = new SendEmailDelegate(smtpClient.Send);
                AsyncCallback cb = new AsyncCallback(SendEmailResponse);
                sd.BeginInvoke(m, cb, sd);
        }
        catch (Exception ex)
        {

            log.Debug("Error While Sending email in attempt");
        }

    }


private delegate void SendEmailDelegate(System.Net.Mail.MailMessage m);
    private static void SendEmailResponse(IAsyncResult ar)
    {
        try
        {
            SendEmailDelegate sd = (SendEmailDelegate)(ar.AsyncState);

            sd.EndInvoke(ar);

            log.Debug("Email Send Sucessfully");
        }
        catch (Exception ex)
        {
            log.Debug("Error While Sending Email -" + ex.InnerException.ToString());

            throw ex;
        }

    }

Thanks,
Rajesh

ASP.NET
ASP.NET
A set of technologies in the .NET Framework for building web applications and XML web services.
3,452 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,838 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Karen Payne MVP 35,401 Reputation points
    2021-11-17T14:57:27.437+00:00

    The following would be executed with a while statement which should have logic to exit after x attempts or use a for/next e.g. after say 5 attempts abort.

    using System;
    using System.ComponentModel;
    using System.Net.Mail;
    using System.Threading.Tasks;
    
    namespace EmailLibrary
    {
        public class Operations
        {
            public delegate void OnSendCompleted(object sender, AsyncCompletedEventArgs eventArguments);
            public static event OnSendCompleted SendCompleted;
    
            public static async Task<(bool success, Exception exception)> SendEmail(MailMessage message)
            {
                try
                {
                    var smtp = new SmtpClient();
    
                    smtp.SendCompleted += OnCompleted;
                    await smtp.SendMailAsync(message);
    
                    return (true, null);
                }
                catch (Exception e)
                {
                    return (false, e);
                }
            }
    
            private static void OnCompleted(object sender, AsyncCompletedEventArgs eventArguments)
            {
                SendCompleted?.Invoke(sender, eventArguments);
            }
        }
    }
    

    Calling, needs message setup

    public async Task Send()
    {
        for (int index = 0; index < 5; index++)
        {
    
            var (success, exception) = await Operations.SendEmail(new MailMessage());
            if (success)
            {
                return;
            }
            else
            {
                // log exception and pause
                await Task.Delay(500);
            }
        }
    }
    

  2. Sadalkar, Rajesh 1 Reputation point
    2021-11-17T16:19:17.467+00:00

    Thank you very much for quick reply.

    Now I am getting this exception.

    An asynchronous operation cannot be started at this time. Asynchronous operations may only be started within an asynchronous handler or module or during certain events in the Page lifecycle. If this exception occurred while executing a Page, ensure that the Page is marked <%@ Page Async="true" %>. This exception may also indicate an attempt to call an "async void" method, which is generally unsupported within ASP.NET request processing. Instead, the asynchronous method should return a Task, and the caller should await it.

    rgds,
    Rajesh


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.