在ASP.NET Core应用程序中,可以使用IHostedService和BackgroundService类来轻松创建后台服务。我们可以将需要执行的任务包装在一个Task中,并在后台服务中添加到队列中,等待执行完成。
以下是实现此操作的步骤:
首先,定义一个后台服务类,它必须从BackgroundService类继承并且实现ExecuteAsync方法。该方法将在后台运行,并执行我们添加到队列中的任务。
public class WorkerService : BackgroundService
{
private readonly IBackgroundTaskQueue _taskQueue;
public WorkerService(IBackgroundTaskQueue taskQueue)
{
_taskQueue = taskQueue;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
var workItem = await _taskQueue.DequeueAsync(stoppingToken);
try
{
//执行我们要添加的任务
await workItem(stoppingToken);
}
catch (Exception ex)
{
//处理任务执行过程中出现的异常
}
}
}
}
然后,定义一个队列类,可用于将任务添加到队列并管理它们。该类必须实现IBackgroundTaskQueue接口。
public interface IBackgroundTaskQueue
{
Task> DequeueAsync(CancellationToken cancellationToken);
void QueueBackgroundWorkItem(Func workItem);
}
public class BackgroundTaskQueue : IBackgroundTaskQueue
{
private ConcurrentQueue> _workItems = new();
private readonly SemaphoreSlim _signal = new(0);
public async Task> DequeueAsync(CancellationToken cancellationToken)
{
await _signal.WaitAsync();
_workItems.TryDequeue(out var workItem);
return workItem;
}
public void QueueBackgroundWorkItem(Func workItem)
{
if (workItem == null)
{
throw new ArgumentNullException(nameof(workItem));
}
_workItems.Enqueue(workItem);
_signal.Release();
}
}
然后,我们可以在控制器的Action方法中将任务添加到队列中。
public class HomeController : Controller
{
private readonly IBackgroundTaskQueue _taskQueue;
public HomeController(IBackgroundTaskQueue taskQueue)
{
_taskQueue = taskQueue;
}
public IActionResult Index()
{
_task