2013-07-29 2 views
0

У меня возникла проблема с трудным воспроизведением, которая, как мне кажется, связана с использованием 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 для начала отмены запросов - из-за настроенного таймаута. Когда это происходит, иногда запрос «застревает» (см. Изображение ниже).

enter image description here

Я ознакомлен с C# асинхронной передовой практики, и я не делаю .Result или .Wait() или тому подобное. Я знаю, что это может привести к зависанию.

Если я передаю CancellationToken.None, проблема исчезнет, ​​поэтому мой намек заключается в том, что он связан с отменой при высоком сценарии параллелизма.

С течением времени все больше и больше запросов начинают свисать, и в итоге у меня нет выбора, кроме как выполнить сброс IIS, чтобы заставить их уйти.

Любые подсказки о том, что может происходить?

ответ

1

Отмена ставки не диктует отмену, исполнитель может ее проверить после очень длительного интервала или полностью игнорировать. правильный способ реализации тайм-аут:

if(yourTask == Task.WhenAny(yourTask, Task.Delay(3000))) 
{ 
    //task completed 
} 
else 
{ 
    //timeout occured 
} 
+0

Я забыл упомянуть, что я использую 'HttpClient.SendAsync' сделать звонки, так что я знаю, за то, что' CancellationToken' не игнорировала полностью. Я добавил это к вопросу. – alextercete

+0

Кроме того, я думаю, что вы забыли «ждать» там до «Task.WhenAny». – alextercete

+0

Почему вы настаиваете на том, чтобы не использовать стандартный путь? я не думаю, что будет измеримая разница в производительности. – TakeMeAsAGuest

 Смежные вопросы

  • Нет связанных вопросов^_^