Я в значительной степени использую пример, предоставленный в документации Microsoft для постановки в очередь фоновых задач .
В этой очереди я добавляю Func<Task>
, который будет выполнен позже QueuedHostedService
.
Контроллер - HTTP POST
...
Func<Task> workItem = () => _mockService.DoWorkAsync(guid);
_queue.QueueBackgroundWorkItem(workItem);
return Ok();
MockService.DoWorkAsync
var data = await _insideMockService.GetAsync();
await _anotherService.Notify(data);
BackgroundTaskQueue.QueueBackgroundWorkItem
private ConcurrentQueue<Func<Task>> _workItems
private SemaphoreSlim _signal = new SemaphoreSlim(0);
public void QueueBackgroundWorkItem(Func<Task> workItem)
{
if (workItem == null)
{
throw new ArgumentNullException(nameof(workItem));
}
_workItems.Enqueue(workItem);
_signal.Release();
}
QueuedHostedService.Executeync
_currentTask = await _queue.DequeueAsync(cancellationToken);
try
{
await _currentTask();
...
BackgroundTaskQueue.DequeueAsync
public async Task<Func<Task>> DequeueAsync(CancellationToken cancellationToken)
{
await _signal.WaitAsync(cancellationToken);
_workItemsById.TryDequeue(out var workItem);
return workItem;
}
Startup.ConfigureServices
services.AddScoped<IMockService, MockService>(); // Implements DoWorkAsync
services.AddScoped<IInsideMockService, InsideMockService>(); // DoWorkAsync requires this dependency
services.AddScoped<IAnotherService, AnotherService>(); // DoWorkAsync requires this dependency
services.AddHostedService<QueuedHostedService>();
services.AddSingleton<IBackgroundTaskQueue, BackgroundTaskQueue>();
IMockService.DoWorkAsync
метод использования scoped
служб.Ссылка на этот метод добавляется в очередь, которая находится в службе singleton
.Эта очередь позже читается HostedService
, который также singleton
.
Есть ли вероятность того, что сервисные ссылки в DoWorkAsync
будут удалены перед обработкой HostedService
?Если исключить сценарии, из-за которых приложение изящно (или неблагодарно) закрывается.
Некоторые локальные тестовые прогоны, возможно, с сотней запросов (и некоторые добавленные Task.Delay
в DoWorkAsync
), кажется, работают нормально, но яя не уверен, что я что-то упустил ..