MediatR会顺序还是并行运行命令?

问题描述 投票:1回答:1

我在应用程序中使用MediatR和CQRS。以下两个语句存在于许多模块中,并且可以在应用程序(这是一个出色的应用程序)中并发调用。

await Mediator.Send(new AddIdCommand { Id = id });
await Mediator.Send(new DeleteIdCommand { Id = id });

以下是命令,它们更新相同的文本文件。

public class AddIdCommand : IRequest
{
    public int Id { get; set; }

    public class AddIdCommandHandler : IRequestHandler<DeleteIdCommand>
    {
        public async Task<Unit> Handle(AddIdCommand request, CancellationToken cancellationToken)
        {
            // .... update the text file with the Id deleted
        }
    }
}

public class DeleteIdCommand : IRequest
{
    public int Id { get; set; }

    public class DeleteIdCommandHandler : IRequestHandler<DeleteIdCommand>
    {
        public async Task<Unit> Handle(DeleteIdCommand request, CancellationToken cancellationToken)
        {
            // .... update the text file with the Id added
        }
    }
}

 ....
    protected IMediator Mediator => _mediator ??= HttpContext.RequestServices.GetService<IMediator>();

两个命令中的Handle(...)是否总是按顺序调用? (因此,无需担心多个进程会更新同一文件的问题。)

c# cqrs mediator mediatr
1个回答
0
投票

嗯,仅从这两行的上下文来看:

await Mediator.Send(new AddIdCommand { Id = id });
await Mediator.Send(new DeleteIdCommand { Id = id });

它将顺序运行。

您可以在此处查看代码:

https://github.com/jbogard/MediatR/blob/master/src/MediatR/Mediator.cs

var requestType = request.GetType();

var handler = (RequestHandlerWrapper<TResponse>)_requestHandlers.GetOrAdd(requestType,
    t => Activator.CreateInstance(typeof(RequestHandlerWrapperImpl<,>).MakeGenericType(requestType, typeof(TResponse))));

return handler.Handle(request, cancellationToken, _serviceFactory);

它只是返回异步Handle方法的任务。因此,如果您等待后续的handle方法,则该方法将同步运行(彼此相对)。

但是您用]结束了问题>

因此无需担心多个进程更新同一文件问题。

而且我不确定。即使您正在等待两个发送方法,如果有两个独立的过程调用这两个方法,并且它们都针对同一文件,则它们之间的顺序将无法得到保证。Mediator.cs对多线程应用程序所做的唯一同步是_requestHandlers是ConcurrentDictionary。

因此,即使并行调用,它也保证该行永远不会初始化同一类型的多个处理程序:

var handler = (RequestHandlerWrapper<TResponse>)_requestHandlers.GetOrAdd(requestType,
        t => Activator.CreateInstance(typeof(RequestHandlerWrapperImpl<,>).MakeGenericType(requestType, typeof(TResponse))));

句柄调用未同步。

© www.soinside.com 2019 - 2024. All rights reserved.