[英]How can I adapt this code to use a single instance instead of creating multiple instances of a service?
我正在編寫一個發送電子郵件的服務,我想同時發送多個 email 通知。 我目前擁有的是:
private void SendInstantMailNotification(string notificationId)
{
MailMessage? message = null;
var notifications = _dbContext
.Notifications
.Where(x => x.Id.Equals(notificationId))
.ToList();
var notification = notifications.First();
message = notification.Content;
Smtp.SendMailSync(message, SmtpConfiguration, Smtp.MailTypeEnum.HTML);
}
代碼的最后一行創建了“SMTP”服務的一個實例。 每次我想發送 email 時,都會創建一個新實例。 如何在不使系統過載的情況下實現僅創建一個實例並多次調用?
這是構造函數:
private readonly NotificationQueueContext _dbContext;
protected NotificationQueueService(NotificationQueueContext dbContext)
{
_dbContext = dbContext;
}
據我了解,您需要一種機制來順序運行某些任務。 所以我創建了一個后台服務,它創建了一個SMTP client
一次和一個ConcurrentQueue
來保存郵件請求並一個一個地運行它們。
該服務將在您的應用程序的整個過程中處於活動狀態,因此其中包含while(TRUE)
。 在每個 email 發送后等待500
毫秒。
如果你想從其他服務發送郵件,你只需要調用RegisterMailRequest
來排隊郵件請求。
您應該將此服務定義為HostedService
,如下所示: services.AddHostedService<SequentialJobHandler>();
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
using MailKit.Net.Smtp;
using Microsoft.Extensions.Hosting;
using MimeKit;
namespace Sample
{
public class SequentialJobHandler : BackgroundService
{
private readonly string MailServerAddress;
private readonly int MailServerPort;
private readonly string AdminEmailAccount;
private readonly string AdminEmailAccountPass;
private readonly string MailUser;
private readonly string MailTitle;
private ConcurrentQueue<MailRequest> queue = new ConcurrentQueue<MailRequest>();
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
using (var client = new SmtpClient())
{
// For demo-purposes, accept all SSL certificates (in case the server supports STARTTLS)
client.ServerCertificateValidationCallback = (s, c, h, e) => true;
await client.ConnectAsync(MailServerAddress, MailServerPort, MailKit.Security.SecureSocketOptions.Auto);
// Note: only needed if the SMTP server requires authentication
await client.AuthenticateAsync(MailUser, AdminEmailAccountPass);
while (true)
{
MailRequest localValue = null;
if (queue.TryDequeue(out localValue))
{
if (localValue != null)
{
SendMail(localValue, client);
}
}
Thread.Sleep(500);
}
//await client.DisconnectAsync(true);
}
}
private async Task SendMail(MailRequest request, SmtpClient client)
{
var message = new MimeMessage();
message.From.Add(new MailboxAddress(MailTitle, AdminEmailAccount));
message.To.Add(new MailboxAddress(request.toUsername, request.toEmail));
message.Subject = request.subject;
message.Body = new TextPart("html")
{
Text = request.body
};
await client.SendAsync(message);
}
public void RegisterMailRequest(MailRequest request)
{
queue.Enqueue(request);
}
public class MailRequest
{
public string toUsername, toEmail, subject, body;
}
}
}
希望這可以幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.