C# MediatR是按顺序还是并行运行这些命令?

C# MediatR是按顺序还是并行运行这些命令?,c#,cqrs,mediator,mediatr,C#,Cqrs,Mediator,Mediatr,我在应用程序中使用MediatR和CQR。以下两条语句存在于许多模块中,并且可以在应用程序中并发调用(它是blazor应用程序) 及 以下是更新同一文本文件的命令 public class AddIdCommand : IRequest { public int Id { get; set; } public class AddIdCommandHandler : IRequestHandler<DeleteIdCommand> { publ

我在应用程序中使用MediatR和CQR。以下两条语句存在于许多模块中,并且可以在应用程序中并发调用(它是blazor应用程序)

以下是更新同一文本文件的命令

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>();
公共类添加命令:IRequest
{
公共int Id{get;set;}
公共类AddCommandHandler:IRequestHandler
{
公共异步任务句柄(AddCommand请求、CancellationToken CancellationToken)
{
//..使用删除的Id更新文本文件
}
}
}
公共类DeleteIdCommand:IRequest
{
公共int Id{get;set;}
公共类DeleteIdCommandHandler:IRequestHandler
{
公共异步任务句柄(DeleteIdCommand请求、CancellationToken CancellationToken)
{
//..使用添加的Id更新文本文件
}
}
}
....
受保护的IMediator中介=>_Mediator???=HttpContext.RequestServices.GetService();

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

好的,仅从以下两行的上下文:

await Mediator.Send(new AddIdCommand { Id = id });
await Mediator.Send(new DeleteIdCommand { Id = id });
它将按顺序运行

您可以在此处看到代码:

var requestType=request.GetType();
var handler=(RequestHandlerWrapper)\u requestHandlers.GetOrAdd(requestType,
t=>Activator.CreateInstance(typeof(RequestHandlerWrapperImpl).MakeGenericType(requestType,typeof(treResponse));
返回处理程序.Handle(请求、取消令牌、_serviceFactory);
它只返回异步句柄方法的任务。 因此,如果您等待后续的handle方法,它将同步运行(相对彼此)

但你的问题以

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

我对此不确定。即使您正在等待两个send方法,如果有两个独立的进程调用这两个方法,并且它们都指向同一个文件,那么它们之间的顺序也无法保证。 对于多线程应用程序,synchronization Mediator.cs所做的唯一工作是_requestHandlers是一个ConcurrentDictionary

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

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

句柄调用是不同步的。

请注意,关于MediatR,sure是肯定的,但是
await
通常表示等待,除非Neathit的blazor应用程序中发生了一些奇怪的事情。他们可能是许多用户同时使用网站。此外,这些语句在某些地方被调用。实际上,在调用handle方法之前,如果首先通过RequestHandlerWrapper,但您可以查看它的实现,它看起来并没有被同步。当然,“它们之间的顺序不能保证”。似乎我需要使用lock{}或使用队列来同步执行。那么事件呢?同一事件的多个事件处理程序是否也按顺序运行?
await Mediator.Send(new AddIdCommand { Id = id });
await Mediator.Send(new DeleteIdCommand { Id = id });
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);
var handler = (RequestHandlerWrapper<TResponse>)_requestHandlers.GetOrAdd(requestType,
        t => Activator.CreateInstance(typeof(RequestHandlerWrapperImpl<,>).MakeGenericType(requestType, typeof(TResponse))));