У вас плохой дизайн. Вместо создания потоков для каждого запроса попробуйте вызвать BeginGetResponse. Фреймворк будет обрабатывать выделение потоков из пула потоков для обслуживания ваших запросов.
Добавить вызов в ServicePointManager.SetDefaultConnectionLimit (?), Не уверенный в этом, к числу, подобному 100.
создать семафор со счетчиком, совпадающим с ограничением числа подключений.
В вашей функции, которая вызывает BeginGetResponse, добавьте вызов semaphore.WaitOne () как раз перед тем, как ваш вызов получит BeginGet ...
В обработчике EndGetResponse () вызовите semaphore.Release (), чтобы продолжить следующий запрос.
Вы, вероятно, исчерпываете пул потоков со всеми своими собственными потоками. Контролируйте свой процесс и посмотрите, не можете ли вы выполнить его и использовать всего 5-10 потоков. Возможно, вы можете войти в Thread.Current.ThreadID, чтобы увидеть, как один и тот же поток обрабатывает несколько запросов.
Сделано это миллиарды раз. На самом деле.