У меня возникла проблема с трудным воспроизведением, которая, как мне кажется, связана с использованием CancellationToken
. У меня есть три асинхронное приложения (каждый на другом сервере), которые обмениваются данными через ASP.NET Web API, как показано на рисунке нижеЗапросы, отмененные сервером при большой нагрузке, зависают на IIS
A ---> B ---> C
App A
запускает процедуру время от времени, запускающего много одновременных запросов к приложение B
, которое, в свою очередь, запускает еще одну пару одновременных запросов к приложению C
. Все эти вызовы выполняются с помощью HttpClient.SendAsync
и ограничены тайм-аута 10 секунд, используя CancellationToken
как таковой:
var cancellationTokenSource = new CancellationTokenSource();
cancellationTokenSource.CancelAfter(TimeSpan.FromSeconds(10));
var token = cancellationTokenSource.Token;
Когда сервер C
находится под большой нагрузкой, он начинает принимать больше времени для ответа, который вызывает сервер B
для начала отмены запросов - из-за настроенного таймаута. Когда это происходит, иногда запрос «застревает» (см. Изображение ниже).
Я ознакомлен с C# асинхронной передовой практики, и я не делаю .Result
или .Wait()
или тому подобное. Я знаю, что это может привести к зависанию.
Если я передаю CancellationToken.None
, проблема исчезнет, поэтому мой намек заключается в том, что он связан с отменой при высоком сценарии параллелизма.
С течением времени все больше и больше запросов начинают свисать, и в итоге у меня нет выбора, кроме как выполнить сброс IIS, чтобы заставить их уйти.
Любые подсказки о том, что может происходить?
Я забыл упомянуть, что я использую 'HttpClient.SendAsync' сделать звонки, так что я знаю, за то, что' CancellationToken' не игнорировала полностью. Я добавил это к вопросу. – alextercete
Кроме того, я думаю, что вы забыли «ждать» там до «Task.WhenAny». – alextercete
Почему вы настаиваете на том, чтобы не использовать стандартный путь? я не думаю, что будет измеримая разница в производительности. – TakeMeAsAGuest