using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Mail;
using System.Threading;
namespace MAF.Mail
{
// 多线程邮件群发
// Mail(单数)表示存储的是能够单独处理的每一封邮件
// Mails(复数)表示存储的是需要进一步处理的一批邮件
public class BulkMail
{
#region 单实例
private static BulkMail _Instance = null;
public static BulkMail Instance
{
get
{
if( null==_Instance )
{
_Instance = new BulkMail();
Thread t = new Thread(new ThreadStart(_Instance.SendMailThreadStart));
t.Start();
}
return _Instance;
}
}
#endregion
// 发邮件服务器
private SmtpClient _Smtp = new SmtpClient("localhost", 25);
// 每封邮件重试次数
private int _RetryTimes = 3;
// 每封邮件超时时间
private int _Timeout = 60000; //毫秒
// 外部存储的邮件队列
Queue<MailsInfo> _WaitingMailsQueue = new Queue<MailsInfo>();
// 待发邮件队列
private Queue<MailInfo> _WaitingMailQueue = new Queue<MailInfo>();
// 已发邮件队列
private List<MailInfo> _SendedMailList = new List<MailInfo>();
//GetMailsMethod CurrentGetMailsMethod;
private SaveMailResultMethod _CurrentSaveMailResultMethod;
// 构造函数
private BulkMail()
{
_Smtp.Timeout = _Timeout; // 每封邮件发送超时时间
}
// 邮件发送线程开始方法,此线程不会终结
private void SendMailThreadStart()
{
while(1==1)
{
if (0 < _WaitingMailsQueue.Count)
{
this.SendBulk();
}
else
{
this.NextBulk();
}
}
}
// 发送邮件(消费待发邮件,生产已发邮件)
private void SendBulk()
{
MailInfo mail = _WaitingMailQueue.Dequeue(); // 出列
try
{
_Smtp.Send(mail.MailMessage); // 发送
mail.Status = MailInfo.State.SendSucceed;
_SendedMailList.Add(mail);
}
catch
{
if( _RetryTimes<=mail.SendTimes ) // 重试次数已够
{
mail.Status = MailInfo.State.SendFailed;
_SendedMailList.Add(mail);
}
else // 重试
{
_WaitingMailQueue.Enqueue(mail);
}
}
finally
{
mail.SendTimes++; // 发送次数加1
}
}
// 从外部读入下一批待发邮件
void NextBulk()
{
if (null != _CurrentSaveMailResultMethod)
{
_CurrentSaveMailResultMethod(_SendedMailList);
_SendedMailList.Clear();
_CurrentSaveMailResultMethod = null;
}
if (0 < _WaitingMailsQueue.Count)
{
MailsInfo mails = _WaitingMailsQueue.Dequeue();
_WaitingMailQueue =new Queue<MailInfo>(mails.GetMails(mails.PageSize, mails.CurrentPage));
_CurrentSaveMailResultMethod = mails.SaveMailResult;
}
else
{
Thread.Sleep(10000);
}
}
#region Public Static Method
/// <summary>
///
/// </summary>
/// <param name="dele">委托</param>
/// <param name="parameters">格式:1,2#3,4#5,6</param>
public void Enqueue(List<MailsInfo> infos)
{
_WaitingMailQueue = new Queue<MailInfo>((IEnumerable<MailInfo>)infos);
}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Mail;
namespace MAF.Mail
{
public delegate List<MailInfo> GetMailsMethod(int pageSize,int currentPage); // 读取外部数据委托
public delegate void SaveMailResultMethod(IList<MailInfo> infos); // 保存执行结果委托
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Mail;
namespace MAF.Mail
{
public class MailsInfo
{
private GetMailsMethod _GetMails = null;
private SaveMailResultMethod _SaveMailResult = null;
private int _PageSize = 0;
private int _CurrentPage = 1;
public GetMailsMethod GetMails
{
get { return _GetMails; }
set { _GetMails = value; }
}
public SaveMailResultMethod SaveMailResult
{
get { return _SaveMailResult; }
set { _SaveMailResult = value; }
}
public int PageSize
{
get { return _PageSize; }
set { _PageSize = value; }
}
public int CurrentPage
{
get { return _CurrentPage; }
set { _CurrentPage = value; }
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Mail;
namespace MAF.Mail
{
public class MailInfo
{
// 枚举 邮件状态
public enum State { WaitForSend = 0, SendFailed = -1, SendSucceed = 1 }
// 受保护成员
protected string _Id = string.Empty; // 邮件标识
protected MailMessage _MailMessage = null; // 邮件内容
protected State _Status = State.WaitForSend; // 邮件状态
protected int _SendTimes = 0; // 邮件发送次数
// 公共方法
public string Id
{
get { return _Id; }
set { _Id = value; }
}
public MailMessage MailMessage
{
get { return _MailMessage; }
set { _MailMessage = value; }
}
public State Status
{
get { return _Status; }
set { _Status = value; }
}
public int SendTimes
{
get { return _SendTimes; }
set { _SendTimes = value; }
}
}
}