MediatR 请求处理程序适用于异步,但如果我删除它则不起作用

MediatR Request Handler works with async but doesn't work if I Remove it

我正在尝试在小型测试应用程序中使用 MediatR Nuget 包。我遇到了一些我能够找到解决方案的问题,这个解决方案让我有点难堪。

这是我构建的一个非常简单的测试 Web 应用程序,用于学习如何使用该库。

在我的 HomeController 中,我进行了以下调用。

Customers = await _mediator.Send(new GetCustomersQuery(0))

我的原始代码是这样的。

public  Task<List<Customer>> Handle(GetCustomersQuery request, CancellationToken cancellationToken)
    {
         return new Task<List<Customer>>(() => {
            if(request.Id == 0)
            {
                return _repo.GetAllCustomers().ToList();
            }
            else
            {
                return new List<Customer>() { _repo.GetCustomerById(request.Id) };
            }
         });
   }

我遇到的行为是,一旦它在我的控制器中触发 await send 调用,它就会坐在那里等待。

我尝试单步执行代码,我正在查看 Mediator class 中的 Send 方法,它看起来像这样:

var handler = (RequestHandlerWrapper<TResponse>)_requestHandlers.GetOrAdd(requestType,
            static t => (RequestHandlerBase)(Activator.CreateInstance(typeof(RequestHandlerWrapperImpl<,>).MakeGenericType(t, typeof(TResponse)))
                                             ?? throw new InvalidOperationException($"Could not create wrapper type for {t}")));

此代码找到我的处理程序并调用 Handle 方法并执行。如果我越过调用并将鼠标悬停在处理程序变量上,我会收到一条文本,说明名称 'handler' 在当前上下文中不存在。我不知道这是否只是调试器的一个怪癖。 (我目前正在使用 Rider)。接下来调用如下

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

如果我进入或越过那条线,它会将我带回调用者,就像它等待异步方法完成一样,我认为这就是它正在做的事情。

我试了一下,查看了一些其他人自己使用的代码,然后在我的处理程序中尝试了这个。

public async Task<List<Customer>> Handle(GetCustomersQuery request, CancellationToken cancellationToken)
    {
        // return new Task<List<Customer>>(() => {
        //     if(request.Id == 0)
        //     {
        //         return _repo.GetAllCustomers().ToList();
        //     }
        //     else
        //     {
        //         return new List<Customer>() { _repo.GetCustomerById(request.Id) };
        //     }
        // });

         return request.Id == 0 ? _repo.GetAllCustomers().ToList() : new List<Customer>() { _repo.GetCustomerById(request.Id) };

    }

这次在 Send 方法中,当我将鼠标悬停在它上面时,处理程序变量仍然给我相同的消息。

这次 return handler.Handle(request, cancellationToken, _serviceFactory); 执行,值 returns 和信息显示在我的页面上。

我不太清楚为什么我的第一种方法不起作用。我不知道是否有太多等待调用串在一起导致问题,或者我是否只是直接错过了 C# 中异步编程的一些基本概念,我的大脑无法鼓起。工作方式有点让我烦恼,因为我的理解是将 async 放在方法中 return 类型的前面是为了在该方法中使用 await 调用。如果我删除我的程序不再构建并且如果我将该逻辑包装在一个新任务中我 运行 进入同一个问题。

任何人都可以帮助我理解或指出一些有助于我更好地理解的信息吗?

感谢托马斯·施密特。他回答了我的问题,我觉得很简单。

我不应该生成新任务,而是应该使用这样的东西:

return Task.FromResult<List<Customer>>(request.Id == 0 ? _repo.GetAllCustomers().ToList() : new List<Customer>() { _repo.GetCustomerById(request.Id) });

谢谢。