微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在C#ASP NET Core中的后台服务内部使用Mediator?

如何解决如何在C#ASP NET Core中的后台服务内部使用Mediator?

我正在尝试使用Mediator实施后台服务QueuedBackground服务。

到目前为止,我能够实现队列,但无法执行Mediator。

界面

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);

现在使用上面的代码,我可以接收类对象,但是当我在调解器中传递它时,我得到的InvalidOperation Handler未注册

我很困惑。

解决方法

好的,我发现了问题

我不得不使用ServiceFactory接口,而不是从构造方法传递它

我的解决方案

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.");
                }
            }
        }
    }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。