[英]MediatR Request Handler works with async but doesn't work if I Remove it
我正在嘗試在小型測試應用程序中使用 MediatR Nuget package。 我遇到了一些我能夠找到解決方案的問題,而這個解決方案讓我有點難堪。
這是我構建的一個非常簡單的測試 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) };
}
});
}
我遇到的行為是,一旦它在我的 controller 中觸發等待發送呼叫,它就會坐在那里等待。
我嘗試單步執行代碼,我正在查看 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 方法並執行。 如果我跨過調用和 hover 跨過處理程序變量,我會收到一條文本,說明名稱“處理程序”在當前上下文中不存在。 我不知道這是否只是調試器的一個怪癖。 (我目前正在使用 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 方法中,處理程序變量仍然給我相同的消息,就像之前我 hover 時一樣。
return handler.Handle(request, cancellationToken, _serviceFactory);
這次執行並返回一個值,信息顯示在我的頁面上。
我不太清楚為什么我的第一種方法不起作用。 我不知道是否有太多等待調用串在一起導致問題,或者我是否只是直接錯過了 C# 中異步編程的一些基本概念,我的大腦無法鼓起。 工作方式有點讓我煩惱,因為我的理解是將異步放在方法中返回類型的前面是為了在該方法中使用 await 調用。 如果我刪除我的程序不再構建,並且如果我將該邏輯包裝在一個新任務中,我會遇到同樣的問題。
任何人都可以幫助我理解或指出一些可以幫助我更好地理解的信息嗎?
感謝托馬斯·施密特。 他回答了我的問題,因為我認為這很簡單。
我不應該生成一個新任務,而是應該使用這樣的東西:
return Task.FromResult<List<Customer>>(request.Id == 0 ? _repo.GetAllCustomers().ToList() : new List<Customer>() { _repo.GetCustomerById(request.Id) });
謝謝你。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.