void SendThreadProc(object state)
        {
            SendMailThreadState threadState = (SendMailThreadState)state;
            int recipientIndex = threadState.recipientIndex;

            try
            {
                SmtpClient smtp = new SmtpClient();
                smtp.Tag = recipientIndex;
                // Catching the following events is not necessary,
                // just make the application more user friendly.
                // If you use the object in asp.net/windows service or non-gui application,
                // You need not to catch the following events.
                // To learn more detail, please refer to the code in EASendMail EventHandler region
                smtp.OnIdle              += new SmtpClient.OnIdleEventHandler(OnIdle);
                smtp.OnAuthorized        += new SmtpClient.OnAuthorizedEventHandler(OnAuthorized);
                smtp.OnConnected         += new SmtpClient.OnConnectedEventHandler(OnConnected);
                smtp.OnSecuring          += new SmtpClient.OnSecuringEventHandler(OnSecuring);
                smtp.OnSendingDataStream += new SmtpClient.OnSendingDataStreamEventHandler(OnSendingDataStream);

                if (UpdateRecipientStatus != null)
                {
                    UpdateRecipientStatus(recipientIndex, "Connecting ...");
                }

                if (threadState.isTestRecipient)
                {
                    smtp.TestRecipients(threadState.server, threadState.mail);
                }
                else
                {
                    smtp.SendMail(threadState.server, threadState.mail);
                }

                if (UpdateRecipientStatus != null)
                {
                    UpdateRecipientStatus(recipientIndex,
                                          threadState.isTestRecipient ?
                                          "Pass":
                                          "******");
                }

                if (UpdateResultCounter != null)
                {
                    UpdateResultCounter(true);
                }
            }
            catch (Exception ep)
            {
                if (UpdateRecipientStatus != null)
                {
                    UpdateRecipientStatus(recipientIndex, ep.Message);
                }

                if (UpdateResultCounter != null)
                {
                    UpdateResultCounter(false);
                }
            }
            finally
            {
                Interlocked.Decrement(ref _threadCounter);
                _trafficController.DecreaseConnection();
            }
        }