gpt4 book ai didi

c# - 如何在 C# ASP NET Core 的后台服务中使用调解器?

转载 作者:行者123 更新时间:2023-12-04 03:53:04 24 4
gpt4 key购买 nike

我正在尝试使用 Mediator 实现后台服务 QueuedBackground 服务。
到目前为止,我能够实现队列,但无法执行 Mediator。
接口(interface)

public interface IBackgroundTaskQueueService
{
void QueueBackgroundWorkItem(object workItem, CancellationToken token);

Task<object> DequeueAsync(
CancellationToken cancellationToken);
}
实现
public class BackgroundTaskQueueService : IBackgroundTaskQueueService
{
private readonly ConcurrentQueue<(object,CancellationToken)> _workItems =
new ConcurrentQueue<(object,CancellationToken)>();

private SemaphoreSlim _signal = new SemaphoreSlim(0);

public void QueueBackgroundWorkItem(object workItem, CancellationToken token)
{
if (workItem == null)
{
throw new ArgumentNullException(nameof(workItem));
}

_workItems.Enqueue((workItem,token));
_signal.Release();
}

public async Task<object> DequeueAsync( CancellationToken cancellationToken)
{
await _signal.WaitAsync(cancellationToken);
_workItems.TryDequeue(out var workItem);
return workItem.Item1;
}
}
后台服务
public class QueuedHostedService : BackgroundService
{

private readonly ILogger _logger;
private readonly IMediator _mediator;
public QueuedHostedService(IBackgroundTaskQueueService taskQueue, ILoggerFactory loggerFactory, IMediator mediator)
{
TaskQueue = taskQueue;
_mediator = mediator;
_logger = loggerFactory.CreateLogger<QueuedHostedService>();
}

public IBackgroundTaskQueueService TaskQueue { get; }

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (false == stoppingToken.IsCancellationRequested)
{
try
{
var workItem = await TaskQueue.DequeueAsync(stoppingToken);
await _mediator.Send(workItem, stoppingToken);
// await _mediator.Send(new UpdateProductCostByMaterialRequestModel()
// {
// Id = 1
// }, stoppingToken);
}
catch (Exception ex)
{
_logger.LogError(ex, $"Error occurred executing Work item.");
}
}
}
}
用法
_queueService.QueueBackgroundWorkItem(new UpdateProductCostByMaterialRequestModel()
{
Id = request.ProductId
}, CancellationToken.None);
现在使用上面的代码,我可以接收类对象,但是当我将它传递给 Mediator 时,我得到 InvalidOperation Handler 未注册。
我很困惑。

最佳答案

好的,我找到了问题
而不是从构造函数传递它,我不得不使用 ServiceFactory 接口(interface)
我的解决方案
BackgroundService 是一个单例。您不能将 Scoped 注入(inject)到 Singleton 中。

public class QueuedHostedService : BackgroundService
{

private readonly ILogger _logger;
private readonly IServiceScopeFactory _serviceScopeFactory;

public QueuedHostedService(IBackgroundTaskQueueService taskQueue, ILoggerFactory loggerFactory, IServiceScopeFactory serviceScopeFactory)
{
TaskQueue = taskQueue;
_serviceScopeFactory = serviceScopeFactory;
_logger = loggerFactory.CreateLogger<QueuedHostedService>();
}

public IBackgroundTaskQueueService TaskQueue { get; }

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
using var scope = _serviceScopeFactory.CreateScope();

var mediator = scope.ServiceProvider.GetRequiredService<IMediator>();
while (false == stoppingToken.IsCancellationRequested)
{
try
{

var workItem = await TaskQueue.DequeueAsync(stoppingToken);
if (workItem is IRequest<object> item)
{
await mediator.Send(workItem, stoppingToken);
}
// await _mediator.Send(new UpdateProductCostByMaterialRequestModel()
// {
// Id = 1
// }, stoppingToken);
}
catch (Exception ex)
{
_logger.LogError(ex, $"Error occurred executing Work item.");
}
}
}
}

关于c# - 如何在 C# ASP NET Core 的后台服务中使用调解器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64141794/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com