который освободит поток в пул, но для выполнения связанной с процессором работы поток возьмет поток из пула потоков. Так что не будет никакой пользы, но будут накладные расходы на переключение потоков. Поэтому постарайтесь избежать этого. Не используйте TPL для работы с процессором.
исал API с использованием asp.net webapi и развернул его в Azure как Appservice. Имя моего контроллера - TestController, а метод действия - что-то вроде ниже.
[Route("Test/Get")]
public string Get()
{
Thread.Sleep(10000);
return "value";
}
Таким образом, для каждого запроса он должен ждать 10 секунд, прежде чем вернуть строку «значение». Я также написал другую конечную точку, чтобы увидеть количество потоков в пуле потоков, работающих для выполнения запросов. Это действие что-то вроде ниже.
[Route("Test/ThreadInfo")]
public ThreadPoolInfo Get()
{
int availableWorker, availableIO;
int maxWorker, maxIO;
ThreadPool.GetAvailableThreads(out availableWorker, out availableIO);
ThreadPool.GetMaxThreads(out maxWorker, out maxIO);
return new ThreadPoolInfo
{
AvailableWorkerThreads = availableWorker,
MaxWorkerThreads = maxWorker,
OccupiedThreads = maxWorker - availableWorker
};
}
Теперь, когда мы выполняем 29 вызовов одновременно для конечной точки Test / Get, для успешного выполнения всех запросов требуется почти 11 секунд. Таким образом, сервер выполняет все запросы одновременно в 11 потоках. Чтобы увидеть состояние потоков, вызов Test / ThreadInfo сразу после вызова Test / Get немедленно возвращается (без ожидания) {"AvailableWorkerThreads": 8161, "MaxWorkerThreads": 8191, "OccupiedThreads": 30}
Кажется, 29 потоков выполняют запросы Test / Get, а 1 поток выполняет запрос Test / ThreadInfo.
Когда я делаю 60 звонков в Test / Get, мне требуется почти 36 секунд, чтобы добиться успеха. Выполнение вызова Test / ThreadInfo (занимает некоторое время) возвращает {"AvailableWorkerThreads": 8161, "MaxWorkerThreads": 8191, "OccupiedThreads": 30}
Если мы увеличиваем количество запросов, значение OccupiedThreads увеличивается. Как и для 1000 запросов, это занимает 2 минуты 22 секунды, а значение OccupiedThreads равно 129.
Кажется, запрос и получение в очередь после 30 одновременных вызовов, хотя в WorkerThread доступно множество потоков. Постепенно это увеличивает поток для одновременного выполнения, но этого недостаточно (129 для 1000 запросов).
Поскольку наши сервисы имеют много вызовов ввода-вывода (некоторые из них являются внешними вызовами API, а некоторые - запросами к базе данных), задержка также высока. Поскольку мы используем все вызовы ввода-вывода асинхронно, сервер может одновременно обслуживать большую часть запросов, но нам нужно больше параллелизма, когда процессор выполняет реальную работу. Мы используем сервисный план S2 с одним экземпляром. Увеличение экземпляра увеличит параллелизм, но нам нужно больше параллелизма из одного экземпляра.
После прочтения некоторого блога и документации по IIS мы увидели настройкуminFreeThreads, Если количество доступных потоков в пуле потоков падает ниже, значение для этого параметра IIS начинает помещать запрос в очередь. Есть ли в appservice что-нибудь подобное? И действительно ли возможно получить больше параллелизма от службы приложений Azure, или нам там не хватает какой-то конфигурации?