HtttpListener и асинхронный метод BeginGetContext
От: gamburger  
Дата: 10.03.14 07:34
Оценка: -1 :)
Мне нужно сделать асинхронный сервер 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 поток? Можно ли расширить макс. кол-во потоков для него?
И еще, если я усыпил поток, разве операционка не должна взять этот спящий и не приносящий никакой пользы поток и запустить на нем второй коллбэк?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.