У меня такой сценарий, когда у меня есть WebApi и конечная точка, которая при срабатывании выполняет много работы (около 2-5 минут). Это конечная точка POST с побочными эффектами, и я хотел бы ограничить выполнение, чтобы, если на эту конечную точку отправлено 2 запроса (не должно быть, но лучше безопасно, чем извините), одному из них придется подождать, чтобы избежать гонки условия.Как заблокировать длинный асинхронный вызов в действии WebApi?
Я первый попытался использовать простой статический замок внутри контроллера, как это:
lock (_lockObj)
{
var results = await _service.LongRunningWithSideEffects();
return Ok(results);
}
это, конечно, не представляется возможным из-за await
внутри lock
заявления.
Другим решением я считал было использовать SemaphoreSlim
реализации, как это:
await semaphore.WaitAsync();
try
{
var results = await _service.LongRunningWithSideEffects();
return Ok(results);
}
finally
{
semaphore.Release();
}
Однако, согласно MSDN:
SemaphoreSlim класс представляет собой легкий, быстрый семафор, который может быть использован для ожидая в течение одного процесса, когда ожидается, что время ожидания будет очень коротким.
Поскольку в этом случае время ожидания может достигать 5 минут, что я должен использовать для контроля параллелизма?
EDIT (в ответ на plog17):
Я понимаю, что, пройдя эту задачу на службу может быть оптимальным способом, однако, я не обязательно хочу стоять в очереди что-то в фоновом режиме, что до сих пор работает после того, как запрос будет выполнен. Запрос включает в себя другие запросы и интеграцию, которые занимают некоторое время, но я все равно хотел бы, чтобы пользователь дождался завершения этого запроса и получил ответ. Этот запрос, как ожидается, будет запускаться только один раз в день в определенное время с помощью задания cron. Тем не менее, есть возможность запустить его вручную разработчиком (в основном, если что-то пойдет не так с заданием), и я хотел бы, чтобы API не запускал проблемы параллелизма, если разработчик, например, дважды посылает запрос случайно и т. д.
Из-за предела полукокса на комментарии, я ответил в форме редактирования так, пожалуйста, проверьте обновленный вопрос. – valorl