十年河东,十年河西,莫欺少年穷
学无止境,精益求精
最近在做项目时,发现项目中有个发邮件的代码,采用的是同步发送邮件,发送多人的话,性能不是一般的低,起初也没有想过改进这块代码,
现在项目上刚好有一个需求,也是发送邮件,而且是写在定时服务中,并且每次要发很多条邮件(上百条还是有的),思来想去,如果采用项目上同步的方式发送邮件,那岂不是要从中午十二点发送到晚上十二点?集团领导晚上十二点收到邮件,被打扰了,那么我的日子也就不长了,很有可能被炒鱿鱼哦。
为了不被炒鱿鱼,只能优化代码了。哈哈
其实,说实在的,原来的邮件发送代码不知道谁封装的,可读性奇差无比,用一个烂字来形容也不为过。
所以,还是自己来封装吧。
废话说多了,直接上代码吧,如下:
配置类:
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; } }