十年河東,十年河西,莫欺少年窮
學無止境,精益求精
最近在做項目時,發現項目中有個發郵件的代碼,采用的是同步發送郵件,發送多人的話,性能不是一般的低,起初也沒有想過改進這塊代碼,
現在項目上剛好有一個需求,也是發送郵件,而且是寫在定時服務中,並且每次要發很多條郵件(上百條還是有的),思來想去,如果采用項目上同步的方式發送郵件,那豈不是要從中午十二點發送到晚上十二點?集團領導晚上十二點收到郵件,被打擾了,那么我的日子也就不長了,很有可能被炒魷魚哦。
為了不被炒魷魚,只能優化代碼了。哈哈
其實,說實在的,原來的郵件發送代碼不知道誰封裝的,可讀性奇差無比,用一個爛字來形容也不為過。
所以,還是自己來封裝吧。
廢話說多了,直接上代碼吧,如下:
配置類:

public class Constants { //郵件相關 public static string mailSmtp = SelectHelper.GetFiled("mailSmtp"); public static string mailSmtpPort = SelectHelper.GetFiled("mailSmtpPort"); public static string mailFrom = SelectHelper.GetFiled("mailFrom"); public static string mailFromPassword = SelectHelper.GetFiled("mailFromPassword"); }
關於SelectHelper的用法,大家可參考我的博客:C# 自定義配置文件
郵件發送類:

public class SendMailHelper { public static string mailSmtp = Constants.mailSmtp; public static string mailSmtpPort = Constants.mailSmtpPort; public static string SmtpPassword = Constants.mailFromPassword; public static string mailFrom = Constants.mailFrom; /// <summary> /// 多線程發送郵件 開辟五個線程且異步 /// </summary> /// <param name="MailToUsers">接收人郵箱 </param> /// <param name="Body">內容</param> /// <param name="Subject">主題</param> public static void SendMailToUser(List<SendMailHelperModel> lst) { try { Parallel.ForEach(lst, new ParallelOptions { MaxDegreeOfParallelism = 5 }, (item, pls, i) => { SendMail(item.MailToUsers, item.Subject, item.Body, item.AttachmentFilesList); }); } catch (Exception ex) { throw ex; } } /// <summary> /// 發送郵件 /// </summary> /// <param name="MailTo">接收郵件的人 多人用逗號分離,譬如:King@xxx.com,Panda@xxx.com</param> private static void SendMail(string MailTo,string Subject,string Body, List<Attachment> AttachmentFilesList) { SmtpClient client = new SmtpClient(mailSmtp, Convert.ToInt32(mailSmtpPort)); if (!(string.IsNullOrEmpty(mailFrom) || string.IsNullOrEmpty(SmtpPassword))) { client.Credentials = new NetworkCredential(mailFrom, SmtpPassword, null); } MailMessage mailMessage = new MailMessage(mailFrom, MailTo); mailMessage.Subject = Subject; mailMessage.Body = Body; mailMessage.IsBodyHtml = true;//是否是HTML郵件 if (AttachmentFilesList != null && AttachmentFilesList.Count > 0) { foreach (Attachment attachment in AttachmentFilesList) { mailMessage.Attachments.Add(attachment); } } client.Send(mailMessage); } } public class SendMailHelperModel { public SendMailHelperModel() { AttachmentFilesList = new List<Attachment>(); } /// <summary> /// 收件人集合 /// </summary> public string MailToUsers { get; set; } /// <summary> /// 郵件主題 /// </summary> public string Subject { get; set; } /// <summary> /// 郵件內容 /// </summary> public string Body { get; set; } /// <summary> /// 郵件附件 /// </summary> public List<Attachment> AttachmentFilesList { get; set; } }
配置文件:

<?xml version="1.0" encoding="utf-8"?> <!--配置文件,用於配置項--> <config> <!--郵件服務器smtp--> <dataConfig value="mailSmtp">smtp.163.com</dataConfig> <!--郵件服務器smtp端口號--> <dataConfig value="mailSmtpPort">25</dataConfig> <!--郵件發送人郵箱--> <dataConfig value="mailFrom">發件人郵箱</dataConfig> <!--郵件發送人密碼--> <dataConfig value="mailFromPassword">發件人密碼</dataConfig> </config>
客戶端代碼如下:

public void sendMails() { SendMailHelperModel M = new SendMailHelperModel(); Attachment atm = new Attachment(@"D:\SDP.zip"); M.AttachmentFilesList.Add(atm); M.Body = "測試附件"; M.MailToUsers = "Kin@movit-tech.com,Pan@movit-tech.com"; M.Subject = "是否能收到附件"; List<SendMailHelperModel> Mlist = new List<SendMailHelperModel>(); Mlist.Add(M); SendMailHelper.SendMailToUser(Mlist); }
當然,本程序采用的是多線程,所以,在一次發送郵件次數不多的情況下,可用同步發送,當然也可以用Task.Run() 異步發送。
如果發送次數特別多,建議使用上述多線程發送。
如果有抄送人員,則代碼如下:
客戶端:

try { List<SendMailHelperModel> Mlist = new List<SendMailHelperModel>(); SendMailHelperModel M = new SendMailHelperModel(); //內容 M.Body = "你好<br/>測試郵件,請勿回復"; //收件人,多人用逗號分隔 M.MailToUsers = PriceLevelService.GetMailToUser(); //抄送人員,多人用,分隔 M.MailToCC = Constants.mailToCC; //主題 M.Subject = "世茂網上招投標平台-價格水平完整性排查提醒"; Mlist.Add(M); SendMailHelper.SendMailToUser(Mlist); } catch (Exception ex) { LogHelper.WriteTextLog(ex); }
郵件幫助類:

public class SendMailHelper { public static string mailSmtp = Constants.mailSmtp; public static string mailSmtpPort = Constants.mailSmtpPort; public static string SmtpPassword = Constants.mailFromPassword; public static string mailFrom = Constants.mailFrom; /// <summary> /// 多線程發送郵件 開辟五個線程且異步 /// </summary> /// <param name="MailToUsers">接收人郵箱 </param> /// <param name="MailToCC">抄送人</param> /// <param name="Body">內容</param> /// <param name="Subject">主題</param> public static void SendMailToUser(List<SendMailHelperModel> lst) { try { Parallel.ForEach(lst, new ParallelOptions { MaxDegreeOfParallelism = 5 }, (item, pls, i) => { SendMail(item.MailToUsers,item.MailToCC, item.Subject, item.Body, item.AttachmentFilesList); }); } catch (Exception ex) { throw ex; } } /// <summary> /// 接收郵件的人 多人用逗號分離,譬如:King@xxx.com,Panda@xxx.com /// </summary> /// <param name="MailTo">接收人 多人用逗號分離,譬如:King@xxx.com,Panda@xxx.com</param> /// <param name="MailToCC">抄送人</param> /// <param name="Subject"></param> /// <param name="Body"></param> /// <param name="AttachmentFilesList"></param> private static void SendMail(string MailTo, string MailToCC, string Subject,string Body, List<Attachment> AttachmentFilesList) { SmtpClient client = new SmtpClient(mailSmtp, Convert.ToInt32(mailSmtpPort)); if (!(string.IsNullOrEmpty(mailFrom) || string.IsNullOrEmpty(SmtpPassword))) { client.Credentials = new NetworkCredential(mailFrom, SmtpPassword, null); } MailMessage mailMessage = new MailMessage(mailFrom, MailTo); mailMessage.CC.Add(MailToCC); mailMessage.Subject = Subject; mailMessage.Body = Body; mailMessage.IsBodyHtml = true;//是否是HTML郵件 if (AttachmentFilesList != null && AttachmentFilesList.Count > 0) { foreach (Attachment attachment in AttachmentFilesList) { mailMessage.Attachments.Add(attachment); } } client.Send(mailMessage); } } public class SendMailHelperModel { public SendMailHelperModel() { AttachmentFilesList = new List<Attachment>(); } /// <summary> /// 收件人集合 /// </summary> public string MailToUsers { get; set; } /// <summary> /// 抄送人集合 /// </summary> public string MailToCC { get; set; } /// <summary> /// 郵件主題 /// </summary> public string Subject { get; set; } /// <summary> /// 郵件內容 /// </summary> public string Body { get; set; } /// <summary> /// 郵件附件 /// </summary> public List<Attachment> AttachmentFilesList { get; set; } }
@天才卧龍的博客