每当我从我的API端点收到一个特定的请求时,我试图按需启动一个后台任务,所有的任务都是发送一封邮件,延迟30秒,所以我认为BackgroundService
是合适的,但问题是它看起来像BackgroundService
主要用于重复任务,而不是按需执行answer。
那么我还有什么其他的选择呢?我希望不必依赖像Hangfire这样的第三方库?我正在使用asp.net core 3.1。
这是我的后台服务。
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace ProjectX.Services {
public class EmailOfflineService : BackgroundService {
private readonly ILogger<EmailOfflineService> log;
private readonly EmailService emailService;
public EmailOfflineService(
ILogger<EmailOfflineService> log,
EmailService emailService
) {
this.emailService = emailService;
this.log = log;
}
protected async override Task ExecuteAsync(CancellationToken stoppingToken)
{
log.LogDebug("Email Offline Service Starting...");
stoppingToken.Register(() => log.LogDebug("Email Offline Service is stopping."));
while(!stoppingToken.IsCancellationRequested)
{
// wait for 30 seconds before sending
await Task.Delay(1000 * 30, stoppingToken);
await emailService.EmailOffline();
// End the background service
break;
}
log.LogDebug("Email Offline Service is stoped.");
}
}
}
3条答案
按热度按时间h7appiyu1#
您可以尝试将异步队列与
BackgroundService
结合使用。通过这种方式,您可以将
IBackgroundTaskQueue
注入到控制器中,并将作业排队到其中,而JobInfo
将包含一些用于在后台执行作业的基本信息,例如:后台队列示例(灵感来自ASP.NET核心文档):
bqjvbblv2#
我认为最简单的方法是在处理发送电子邮件请求的代码中进行一个“发射后忘记”调用,如下所示-
这将启动一个发送电子邮件的线程。代码将立即返回给调用者。在EmailOffline方法中,您可以根据需要包含时间延迟逻辑。请确保也包含错误日志记录逻辑,否则EmailOffline的异常可能会被默默地吞掉。
附言-回答Coastpear和FlyingV -
不需要考虑调用上下文的结束。这项工作将在一个单独的线程上完成,它完全独立于调用上下文。
我已经在生产中使用类似的机制几年了,到目前为止零问题。
如果你的站点不是特别忙碌,而且工作也不是很重要,这是最简单的解决方案。只要确保你在你的工作器中捕获并记录错误(在这个例子中是EmailOffline)。
如果您需要更可靠的解决方案,我建议使用成熟的队列产品,如AWS SQS,不要费心自己创建一个,创建一个真正好的队列系统并不容易。
0ve6wy6x3#
使用Hangfire,它的后台方法功能非常棒,并免费为您提供一个漂亮的 Jmeter 板:https://docs.hangfire.io/en/latest/background-methods/index.html