基于阻塞队列BlockingCollection实现异步消息队列
消息处理父类:
/// <summary>
/// 异步消息处理
/// </summary>
public abstract class AsyncProcessor<TMessage>
{
private readonly BlockingCollection<TMessage> _messageQueue = new BlockingCollection<TMessage>(2048);
private readonly Thread _processThread = null;
public AsyncProcessor(int threadCount)
{
if (i<=0)
{
throw new ArgumentException("threadCount必须大于0");
}
for (int i = 0; i < threadCount; i++)
{
this._processThread = new Thread(this.Dequeue)
{
IsBackground = true
};
this._processThread.Start();
}
}
/// <summary>
/// 消息入队
/// </summary>
/// <param name="message"></param>
public void Enqueue(TMessage message)
{
if (this._messageQueue.IsAddingCompleted)
{//不使用BlockingCollection,直接处理消息
this.ProcessMessage(message);
return;
}
this._messageQueue.Add(message);
}
/// <summary>
/// 消息出队
/// </summary>
private void Dequeue()
{
try
{
foreach (var message in this._messageQueue.GetConsumingEnumerable())
{
this.ProcessMessage(message);
}
}
catch (Exception ex)
{
try
{
this._messageQueue.CompleteAdding();
}
catch (Exception ex1)
{
}
}
}
/// <summary>
/// 消息处理
/// </summary>
/// <param name="message"></param>
protected abstract void ProcessMessage(TMessage message);
}
具体的消息处理类:
/// <summary>
/// 邮件发送器(必须注册成单例)
/// </summary>
public class EmailAsyncProcessor : AsyncProcessor<EmailMessage>
{
private ILogger<EmailAsyncProcessor> _logger = null;
private EmailSender _emailSender = null;
private string _connectionString { get; set; }
public EmailAsyncProcessor(IConfiguration configuration, ILogger<EmailAsyncProcessor> logger):base(1)//使用一个线程处理消息
{
this._connectionString = configuration["ConnectionStrings:DefaultConnection"];
var emailOption = configuration.GetSection("EmailOptions").Get<EmailOptions>();//configuration.GetValue<EmailOptions>("EmailOptions");
this._logger = logger;
#if DEBUG
this._emailSender = new EmailSender("smtp.qq.com", emailOption.Port, "410577910@qq.com", "xxxxxxxx");
#else
this._emailSender = new EmailSender(emailOption.SmtpServer, emailOption.Port);
#endif
}
protected override void ProcessMessage(EmailMessage emailMessage)
{
var emailRecord = emailMessage.EmailRecord;
var emailSendState = EIsSendedEmail.已发送;
//发送邮件
try
{
emailRecord.Email = emailRecord.Email.Replace(CONST.GUEST_SUFFIX, "");
#if DEBUG
this._emailSender.SendMail(emailRecord.Title, emailRecord.Content, "410577910@qq.com", emailRecord.Email);
#else
this._emailSender.SendMail(emailRecord.Title, emailRecord.Content, emailMessage.FromEmail, emailRecord.Email);
#endif
}
catch (Exception ex)
{
_logger.LogError("邮件发送失败:" + ex.Message);
emailSendState = EIsSendedEmail.发送失败;
}
if (!string.IsNullOrWhiteSpace(this._connectionString))
{
using (MySqlConnection sqlConnection = new MySqlConnection(this._connectionString))
{
using (MySqlCommand sqlCommand = new MySqlCommand())
{
sqlConnection.Open();
sqlCommand.Connection = sqlConnection;
sqlCommand.CommandType = CommandType.Text;
sqlCommand.Connection = sqlConnection;
sqlCommand.CommandText = $"UPDATE `{nameof(Email_record)}` SET `SendState`=@SendState WHERE ID=@ID";
sqlCommand.Parameters.AddRange(new MySqlParameter[] {
new MySqlParameter("@ID",emailRecord.ID),
new MySqlParameter("@SendState",emailSendState)
});
sqlCommand.ExecuteNonQuery();
}
}
}
}
}
public class EmailMessage
{
/// <summary>
/// 发送人邮箱
/// </summary>
public string FromEmail { get; set; }
/// <summary>
/// 发送记录
/// </summary>
public Email_record EmailRecord { get; set; }
}
发送消息:
var emailProcessor = this._serviceLocator.Resolve<EmailAsyncProcessor>()
emailProcessor.Enqueue(new EmailMessage { FromEmail = shopInfo.ServiceEmail, EmailRecord = emailRecord });
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?