В одном из проектов подключена библиотека MediatR.
Используя абстракции из данной библиотеки определил команду:
public class TestCommand: IRequest
{ }
и обработчик данной команды:
public class TestHandler : IAsyncRequestHandler<TestCommand>
{
public Task Handle(TestCommand command)
{
return Task.Factory.StartNew(() =>
{
// Здесь намеренно бросается исключение.
throw new ApplicationException();
});
}
}
Далее в контроллер инжектится сам IMediator
, через который мы можем вызвать нужный обработчик для конкретной команды.
Контроллер:
public class HomeController : Controller
{
private readonly IMediator _mediator;
public HomeController(IMediator mediator)
{
_mediator = mediator;
}
public ActionResult Index()
{
try
{
// Передаем команду, тем самым вызываем обработчик данной команды - TestHandler.
_mediator.Send(new TestCommand()).Wait();
}
catch (Exception e)
{
// Сюда никогда не попадаем
}
return View();
}
}
Суть проблемы:
Как можно заметить, в методе Handle
класса TestHandler
, который обрабатывает команду TestCommand
создается и возвращается новая задача, в которой просто бросается исключение ApplicationException
.
Далее в экшене Index
контроллера Home
, к возвращаемой из TestHandler.Handle
задаче применен метод Wait()
, который должен дождаться ее выполнения. Так как в возвращенной задаче бросается исключение ApplicationException
мы по идее должны попасть в блок catch
, но этого не происходит, вместо этого, такое ощущение, что возникает какой-то deadlock
.
Собственно вопрос, это баг в библиотеке или я что-то упустил и не заметил и данное поведение нормально?
P.S. Если заменить
_mediator.Send(new TestCommand()).Wait();
на
await _mediator.Send(new TestCommand());
то поведение будет ожидаемым, т.е. мы попадем в блок catch
. Но лично мне хотелось бы понять, почему код перестает работать если используется метод Wait()
Автор библиотеки не удосужился вызвать ConfigureAwait(false) (RequestHandler.cs), так что внутри библиотеки произошёл захват контекста, а вы вызовом Wait() заблокировали поток, в который должно вернуться управление, так что произошёл классический deadlock с async/await, можете почитать детальный разбор тут Еще один аргумент за ConfigureAwait(false) в библиотеках
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Привет всемРебят, помогите исправить глупейшую ошибку в логике:
Необходимо выполнить сегментацию водоразделом для дальнейшей работыНашла на openCv, но не до конца получается преобразовать в OpenCvSharp
Недавно начал баловаться с unity, стал смотреть примеры скриптов и наткнулся на такую конструкцию: