zoukankan      html  css  js  c++  java
  • 自己封装的一个支持回调和独立线程的异步发送邮件的类

    经常看到有很多朋友在网上找发送邮件的代码,也经常有很多朋友问各种邮件发送中出的问题,

    因此把自己写的一个邮件发送类整理了一下,贴出来,给大家参考借鉴。虽然这个代码不算完整,

    但贵在简练实用,便于阅读和修改扩展,里面还包含了写日志的简练方法,非常实用。


    特色:

     代码简洁短小,逻辑清晰,便于大家拓展修改。

    支持群发,一封邮件指定多名接收人。

    使用独立线程,不影响主程序运行。采用异步发送,最大程度降低系统消耗。

    使用队列,对意外发送不成功邮件,可以重复发送,提高成功率。

    支持回调,可以了解发送失败的详细错误信息,便于调试和修正。

    支持错误日志,实时记录各种异常状况。


     
    /*** 王海斌 2016-05-22 qq:443053303  版权所有,请勿传播 ***
     *
     * 邮件发送类
     *
     * 特色:
     * 1:独立线程,不影响主程序运行
     * 2:使用队列,对意外发送不成功邮件,可以重复发送,提高成功率
     * 3:支持回调,可以了解发送失败的详细错误信息,便于调试和修正
     * 4:错误日志,实时记录各种异常状况
     * 5:支持群发
     * 6:代码简洁,逻辑清晰,便于大家拓展修改
     *
     * 注意:
     * 1:该代码从项目中删减而来,一些安全、校验、特别处理等等业务代码,都过滤了,大家自己添加
     * 2:邮件回调方法里,可以探视多种发送邮件服务返回的消息,这里没写那么多,大家自己完善
     * 3:只开放日志方法、添加待发送邮件、发送邮件三个方法。
     * 4:日志方法和邮件发送方法,都可以独立使用
     * 5:邮件队列采用List<>模拟,简洁实用,发邮件足够
     * 6:该代码删减后未做测试,如有错漏,请与我联系
     *
     *** 王海斌 2016-05-22 qq:443053303  版权所有,请勿传播 ***/
    
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Net;
    using System.Net.Mail;
    using System.Text;
    using System.Web;
    using System.Linq;
    using System.Threading;
    namespace Common
    {
        public class MyEmail
        {
            public string Subject { get; set; }
            public string Body    { get; set; }
            public string Tos     { get; set; }
            public string From    { get; set; }
            public int id         { get; set; }
            public int Status     { get; set; }//0:未发送,1:发送中,2:已发送,3:发送失败
            public int SendCnt    { get; set; }
            public MyEmail()
            {
                Status = 0;
                SendCnt = 0;
            }
        }
        public static class EMailHelper
        {
            #region 邮件静态属性
            private static string SmtpServer = "outlook.office365.com";      //邮件服务器
            private static string From = "testSend@hotmail.com";             //默认发件箱
            private static string Name = "Hotmail Tester";                   //默认发件箱名字
            private static string Password = "Test123";                      //默认发件箱密码
            private static int SmtpServerPort = 587;                         //邮件服务器端口
            private static int Timeout = 60000;                              //超时时间
            private static List<MyEmail> Mails = new List<MyEmail>();        //待发邮件列表
            private static bool IsRun = false;                               //发邮件线程是否启动
            #endregion
            #region 日志方法
            private static object LockObj = new object();
            private static string logPath = ConfigurationManager.AppSettings["LogPath"];
            public static bool WriteLog(string str)
            {
                lock (LockObj)
                {
                    string fileName = System.DateTime.Now.ToLongDateString() + ".log";
                    try
                    {
                        if (!Directory.Exists(logPath))
                        {
                            Directory.CreateDirectory(logPath);
                        }
                        string nowTime = System.DateTime.Now.ToString();
                        StreamWriter sw = new StreamWriter(logPath + fileName, true);
                        sw.Write("【" + nowTime + "】" + str + "
    ");
                        sw.Flush();
                        sw.Close();
                        return true;
                    }
                    catch
                    {
                        return false;
                    }
                }
            }
            #endregion
            public static void Add(VivaEmail mail)
            {
                mail.id = Mails.Count < 1 ? 1 : Mails.Max(p => p.id) + 1;
                Mails.Add(mail);
                if (!IsRun)
                {
                    ThreadPool.QueueUserWorkItem(new WaitCallback(StartSend));
                    IsRun = true;
                }
            }
            public static string Send(email)
            {
                var errMsg = "";
                try
                {
                    var client = new SmtpClient(SmtpServer, SmtpServerPort);
                    client.UseDefaultCredentials = true;
                    client.Credentials = new NetworkCredential(From, Password);
                    client.DeliveryMethod = SmtpDeliveryMethod.Network;
                    client.EnableSsl = true;
                    client.Timeout = Timeout;
    
                    var mailMessage = new MailMessage();
                    mailMessage.From = new MailAddress(From, Name, Encoding.UTF8);
                    foreach (var to in email.tos)//抄送和密送人写法类似,如有需要,自己添加
                    {
                         if (!string.IsNullOrWhiteSpace(to))
                         {
                             mailMessage.To.Add(to);
                         }
                    }
                    mailMessage.Subject = email.Subject;
                    mailMessage.SubjectEncoding = Encoding.UTF8;
                    mailMessage.Body = email.Body;
                    mailMessage.IsBodyHtml = true;
                    mailMessage.BodyEncoding = Encoding.UTF8;
                    mailMessage.IsBodyHtml = true;
                    mailMessage.Priority = MailPriority.High;
    
                    object userState = mailMessage;
                    client.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback);
                    client.SendAsync(mailMessage, email);
                }
                catch (Exception ex)
                {
                    return ex.Message;
                }
                return errMsg;
            }
    
            private static void SendCompletedCallback(object sender, AsyncCompletedEventArgs e)
            {
                var mail = e.UserState as MyEmail;
                if (e.Error != null)
                {
                    Log.WriteLog("邮件【" + mail.To + ":" + mail.Subject + "】发送失败!" + "
    " + e.Error.Message);
                    mail.Status = 3;
                }
                else
                {
                    Mails.Remove(mail);
                }
            }
            private static void StartSend(object obj)
            {
                while (true)
                {
                    var mail = Mails.FirstOrDefault(p => p.Status == 0 && p.SendCnt < 3);
                    if (mail != null)
                    {
                        if (!string.IsNullOrWhiteSpace(mail.Tos))
                        {
                            Send(mail);
                            mail.SendCnt += 1;
                            mail.Status = 1;
                        }
                        else
                        {
                            mail.Status = 3;
                        }
                    }
                    Thread.Sleep(500);
                }
            }
        } 
    }
    

  • 相关阅读:
    【JMeter】if语句中不能Failure=false解决办法
    【java】method.invoke(方法底层所属对象/null,new Object[]{实际参数})
    【java设计模式】【行为模式Behavioral Pattern】模板方法模式Template Method Pattern
    【java设计模式】代理模式
    33-算法训练 安慰奶牛
    32-java 里面list的问题
    31-java中知识总结:list, set, map, stack, queue
    30-算法训练 最短路 spfa
    29-算法训练 结点选择-超时了!!!
    28-算法训练 最大最小公倍数 -贪心
  • 原文地址:https://www.cnblogs.com/foren/p/6009081.html
Copyright © 2011-2022 走看看