C# 使用系統方法發送異步郵件


項目背景:

最近在對幾年前的一個項目進行重構,發現發送郵件功能需要一定的時間來處理,而由於發送是同步的因此導致在發送郵件時無法執行后續的操作

實際上發送郵件后只需要將發送結果寫入系統日志即可對其他業務沒有任何影響,因此決定將發送郵件操作更改為異步的
 
由於使用的是C#的郵件類庫,而C#本身已經提供了異步發送的功能即只需要將Send方法更改為SendAsync即可,更改方法名並不難但發送后再寫入日志就有點難了
因為項目中發送郵件是單獨的組件,所以我不可能在發送郵件類庫中直接添加寫入日志操作(不在同一個類庫,網絡和MSDN上的例子都是同一組件下)
但C#可以使用委托將方法作為參數來傳遞的,因此我就可以在發送郵件的方法中添加一個回調方法,在異步發送郵件后再執行回調方法即可
 
完整代碼:
/******************************************************************
 * 創建人:HTL
 * 創建時間:2015-04-16 21:34:25
 * 說明:C# 發送異步郵件Demo
 * Email:huangyuan413026@163.com
 *******************************************************************/
using System;
using System.Net.Mail;
namespace SendAsyncEmailTest
{
    class Program
    {
        const string dateFormat = "yyyy-MM-dd :HH:mm:ss:ffffff";
        static void Main(string[] args)
        {
            Console.WriteLine("開始異步發送郵件,時間:" + DateTime.Now.ToString(dateFormat));
            new MailHelper().SendAsync("Send Async Email Test", "This is Send Async Email Test", "huangyuan413026@163.com", emailCompleted);
            Console.WriteLine("郵件正在異步發送,時間:" + DateTime.Now.ToString(dateFormat));
            Console.ReadKey();
            Console.WriteLine();
        }
        /// <summary>
        /// 郵件發送后的回調方法
        /// </summary>
        /// <param name="message"></param>
        static void emailCompleted(string message)
        {
            //延時1秒
            System.Threading.Thread.Sleep(1000);
            Console.WriteLine();
            Console.WriteLine("郵件發送結果:\r\n" + (message == "true" ? "郵件發送成功" : "郵件發送失敗") + ",時間:" + DateTime.Now.ToString(dateFormat));
            //寫入日志
        }
    }
    /// <summary>
    /// 發送郵件類
    /// </summary>
    public class MailHelper
    {
        public delegate int MethodDelegate(int x, int y);
        private readonly int smtpPort = 25;
        readonly string SmtpServer = "smtp.baidu.com";
        private readonly string UserName = "support@baidu.com";
        readonly string Pwd = "baidu.com";
        private readonly string AuthorName = "BaiDu";
        public string Subject { get; set; }
        public string Body { get; set; }
        public string Tos { get; set; }
        public bool EnableSsl { get; set; }
        MailMessage GetClient
        {
            get
            {

                if (string.IsNullOrEmpty(Tos)) return null;
                MailMessage mailMessage = new MailMessage();
                //多個接收者                
                foreach (string _str in Tos.Split(','))
                {
                    mailMessage.To.Add(_str);
                }
                mailMessage.From = new System.Net.Mail.MailAddress(UserName, AuthorName);
                mailMessage.Subject = Subject;
                mailMessage.Body = Body;
                mailMessage.IsBodyHtml = true;
                mailMessage.BodyEncoding = System.Text.Encoding.UTF8;
                mailMessage.SubjectEncoding = System.Text.Encoding.UTF8;
                mailMessage.Priority = System.Net.Mail.MailPriority.High;
                return mailMessage;
            }
        }
        SmtpClient GetSmtpClient
        {
            get
            {
                return new SmtpClient
                {
                    UseDefaultCredentials = false,
                    Credentials = new System.Net.NetworkCredential(UserName, Pwd),
                    DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network,
                    Host = SmtpServer,
                    Port = smtpPort,
                    EnableSsl = EnableSsl,
                };
            }
        }
        //回調方法
        Action<string> actionSendCompletedCallback = null;
        ///// <summary>
        ///// 使用異步發送郵件
        ///// </summary>
        ///// <param name="subject">主題</param>
        ///// <param name="body">內容</param>
        ///// <param name="to">接收者,以,分隔多個接收者</param>
        //// <param name="_actinCompletedCallback">郵件發送后的回調方法</param>
        ///// <returns></returns>
        public void SendAsync(string subject, string body, string to, Action<string> _actinCompletedCallback)
        {
            if (string.IsNullOrEmpty(to)) return;

            Tos = to;

            SmtpClient smtpClient = GetSmtpClient;
            MailMessage mailMessage = GetClient;
            if (smtpClient == null || mailMessage == null) return;
            Subject = subject;
            Body = body;
            EnableSsl = false;
            //發送郵件回調方法
            actionSendCompletedCallback = _actinCompletedCallback;
            smtpClient.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback);
            try
            {
                smtpClient.SendAsync(mailMessage, "true");//異步發送郵件,如果回調方法中參數不為"true"則表示發送失敗
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
            finally
            {
                smtpClient = null;
                mailMessage = null;
            }
        }
        /// <summary>
        /// 異步操作完成后執行回調方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SendCompletedCallback(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            //同一組件下不需要回調方法,直接在此寫入日志即可
            //寫入日志
            //return;
            if (actionSendCompletedCallback == null) return;
            string message = string.Empty;
            if (e.Cancelled)
            {
                message = "異步操作取消";
            }
            else if (e.Error != null)
            {
                message = (string.Format("UserState:{0},Message:{1}", (string)e.UserState, e.Error.ToString()));
            }
            else
                message = (string)e.UserState;
            //執行回調方法
            actionSendCompletedCallback(message);
        }
    }
}

 

有圖有真相

 



 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM