##_导言
在我前一篇文章中, 我详述了如何使用流利电子邮件和 SMTP 客户端@. 发送邮件。 但其中一个问题是发电邮的延迟速度很慢,
这样用户就可以继续使用此应用程序, 不必等待电子邮件发送@. @这是网络应用中常见的模式,
ASP.NET 核心中的背景选项
在 ASP.NET 核心中, 您有两个主要选项 {( 除了更高级的选项, 比如杭大火 /Quartz)}
- iHosted Service {-}% 此选项为您提供基本生命周期管理的基本背景任务@. 您可以开始并停止此服务, 它将在背景中运行.
- Ihosted Lifetime {-}% 此选项使您更能控制您的背景任务的生命周期}. 您也可以开始和停止此服务, 它将在后台运行, 但是您有更大的控制 roundn 启动@,_ stop, 开始 @,} 停止等+...}
在此例中, I'll 使用简单的 IHOD Service 在背景中发送邮件@ .
源代码
此消息的完整来源如下: @.
Background Email Service
using System.Threading.Tasks.Dataflow;
using Mostlylucid.Email.Models;
namespace Mostlylucid.Email
{
public class EmailSenderHostedService(EmailService emailService, ILogger<EmailSenderHostedService> logger)
: IHostedService, IDisposable
{
private readonly BufferBlock<BaseEmailModel> _mailMessages = new();
private Task _sendTask = Task.CompletedTask;
private CancellationTokenSource cancellationTokenSource = new();
public async Task SendEmailAsync(BaseEmailModel message)
{
await _mailMessages.SendAsync(message);
}
public Task StartAsync(CancellationToken cancellationToken)
{
logger.LogInformation("Starting background e-mail delivery");
// Start the background task
_sendTask = DeliverAsync(cancellationTokenSource.Token);
return Task.CompletedTask;
}
public async Task StopAsync(CancellationToken cancellationToken)
{
logger.LogInformation("Stopping background e-mail delivery");
// Cancel the token to signal the background task to stop
await cancellationTokenSource.CancelAsync();
// Wait until the background task completes or the cancellation token triggers
await Task.WhenAny(_sendTask, Task.Delay(Timeout.Infinite, cancellationToken));
}
private async Task DeliverAsync(CancellationToken token)
{
logger.LogInformation("E-mail background delivery started");
while (!token.IsCancellationRequested)
{
BaseEmailModel? message = null;
try
{if(_mailMessages.Count == 0) continue;
message = await _mailMessages.ReceiveAsync(token);
switch (message)
{
case ContactEmailModel contactEmailModel:
await emailService.SendContactEmail(contactEmailModel);
break;
case CommentEmailModel commentEmailModel:
await emailService.SendCommentEmail(commentEmailModel);
break;
}
logger.LogInformation("Email from {SenderEmail} sent", message.SenderEmail);
}
catch (OperationCanceledException)
{
break;
}
catch (Exception exc)
{
logger.LogError(exc, "Couldn't send an e-mail from {SenderEmail}", message?.SenderEmail);
await Task.Delay(1000, token); // Delay and respect the cancellation token
if (message != null)
{
await _mailMessages.SendAsync(message, token);
}
}
}
logger.LogInformation("E-mail background delivery stopped");
}
public void Dispose()
{
cancellationTokenSource.Cancel();
cancellationTokenSource.Dispose();
}
}
}
public class EmailSenderHostedService(EmailService emailService, ILogger<EmailSenderHostedService> logger)
: IHostedService, IDisposable
{
private readonly BufferBlock<BaseEmailModel> _mailMessages = new();
private Task _sendTask = Task.CompletedTask;
private CancellationTokenSource cancellationTokenSource = new();
我们也设置了一个新的任务, 在背景中发送电子邮件@. @% 取消源代码, 当我们想停止服务时会优雅地取消任务@. @%
然后我们用StartAsync 启动托管服务,并为其他服务提供切入点,发送电子邮件@.
public async Task SendEmailAsync(BaseEmailModel message)
{
await _mailMessages.SendAsync(message);
}
public Task StartAsync(CancellationToken cancellationToken)
{
logger.LogInformation("Starting background e-mail delivery");
// Start the background task
_sendTask = DeliverAsync(cancellationTokenSource.Token);
return Task.CompletedTask;
}
在我们的设置类中,我们现在需要 注册服务 在DI集装箱 并启动主机服务
services.AddSingleton<EmailSenderHostedService>();
services.AddHostedService(provider => provider.GetRequiredService<EmailSenderHostedService>());
现在我们可以通过电子邮件SenderHosted Servicice@. 调用发送邮件Async方法, @ .g., 用于我们做的联系表@.
var contactModel = new ContactEmailModel()
{
SenderEmail = user.email,
SenderName =user.name,
Comment = commentHtml,
};
await sender.SendEmailAsync(contactModel);
在上文的代码中,这又增加了这一信息。 BufferBlock<BaseEmailModel> _邮件mailMessages 和背景任务将接收并发送电子邮件@. @%
private async Task DeliverAsync(CancellationToken token)
{
...
while (!token.IsCancellationRequested)
{
BaseEmailModel? message = null;
try
{if(_mailMessages.Count == 0) continue;
message = await _mailMessages.ReceiveAsync(token);
switch (message)
{
case ContactEmailModel contactEmailModel:
await emailService.SendContactEmail(contactEmailModel);
break;
case CommentEmailModel commentEmailModel:
await emailService.SendCommentEmail(commentEmailModel);
break;
}
logger.LogInformation("Email from {SenderEmail} sent", message.SenderEmail);
...
}
logger.LogInformation("E-mail background delivery stopped");
}
这将循环到我们停止服务, 并继续监视缓冲锁以获取发送@.}的新邮件
Finding related posts...