您的位置:首页 > 其它

自己封装的一个支持回调和独立线程的异步发送邮件的类

2016-05-22 14:00 591 查看
经常看到有很多朋友在网上找发送邮件的代码,也经常有很多朋友问各种邮件发送中出的问题,

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

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

特色:

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

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

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

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

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

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

 
/*** 王海斌 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 + "\r\n");
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 + "】发送失败!" + "\n" + 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);
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息