Мы используем асинхронный HttpHandler в ASP.NET 3.5 под IIS 6, и в нашем коде мы хотим выполнить внешний вызов API, если мы не слишком загружены. Мы определили «слишком большую нагрузку», что означает, что если к этому API одновременно обращаются более X запросов, мы просто пропустим вызов API.
Для этого мы завернули наш код в семафор и попробовали / поймали / наконец. Мне кажется, что этот код не может быть выполнен без освобождения семафора, но с некоторыми дополнительными журналами мы видим, что при большой нагрузке оператор release никогда не вызывается.
Код такой:
static Semaphore requestLimiter = new Semaphore(500, 500);
...
String GetResultFromAPI() {
if (!requestLimiter.WaitOne(0)) return null;
try
{
// ... code to perform API call, with a timeout specified on the HttpWebRequest
return result;
} catch { /* ignore exceptions */ }
finally
{
requestLimiter.Release();
}
return null;
}
Мы видели исключения для истечения времени ожидания HttpWebRequest, поэтому мы озадачены тем, как этот код может привести к тому, что семафор requestLimiter сбрасывается до 0 и никогда не восстанавливается.
Кто-нибудь сталкивался с этим? Есть ли способ, которым асинхронный HttpHandler может прервать запрос без исключения?
Редактировать
Очевидно, что ThreadAbortExceptions - отвратительный зверь, под которым этот код обязательно потерпит неудачу. Мы явно не вызываем Thread.Abort, и я не думаю, что HttpWebRequest будет. Однако теперь пересмотренный вопрос таков: вызывает ли ASP.NET когда-либо Thread.Abort для асинхронных http-запросов?