Мне нужно сделать асинхронный сервер HtttpListener, который бы работал под большой нагрузкой. В инете полно различных реализаций такого сервера, начиная от вызова синхронного метода-слушателя GetContext в бесконечном цикле (потом обработчики запускаются в разных потоках, либо каждый раз в новых, либо из пула) и заканчивая реализацией с использованием асинхронных слушателей BeginGetContext , которые потом должны запускать обработчики. И у меня несколько вопросов:
1) почему при наличии готового асинхронного слушателя BeginGetContext , в инете полно других реализаций (почему разрабы просто не юзают готовый BeginGetContext, может быть он глючный\непроизводительный или еще чего? можно ли его юзать в высоконагруженном асинхронном приложении?)
2) юзает ли BeginGetContext пул потоков, или каждый раз при своем вызове должен создавать новый поток?
3)и самая большая проблема сейчас — я написал код с использованием Thread.Sleep и такое ощущение, что BeginGetContext всегда запускает обработчики в одном и том же потоке.
Вот код:
public class Server
{
private readonly HttpListener listener;
public Server(string prefix)
{
listener = new HttpListener();
listener.Prefixes.Add(prefix);
listener.Start();
//стартовый вызов слушателя
IAsyncResult result = listener.BeginGetContext(CallBackHandler, listener);
Console.Read();
}
private void CallBackHandler(IAsyncResult result)
{
// поставили БРЯК на строке ниже
HttpListenerContext context = listener.EndGetContext(result);
//зацикливаем вызов слушателя
IAsyncResult res = listener.BeginGetContext(CallBackHandler, listener);
System.Threading.Thread.Sleep(20000);
}
}
Я не знаю, почему, но если в браузере выполнить 2 запроса почти одновременно на мой сервер, то первый каллбэк выполняется сразу, а второй почему-то начинает выполняться только после окончания 20 секунд, то есть, после окончания первого каллбэка. Это заметно, так как бряк на 2-м запросе срабатывает только через 20 сек после запроса. Почему такое происходит? Это же не многопоточное приложение, так как потоки выполняются последовательно, тогда зачем нужен этот BeginGetContext ?
А может, BeginGetContext юзает пул и в нем всего 1 поток? Можно ли расширить макс. кол-во потоков для него?
И еще, если я усыпил поток, разве операционка не должна взять этот спящий и не приносящий никакой пользы поток и запустить на нем второй коллбэк?