c# - HttpListener in mono can't process more than 2 requests in the same time? -


i faced problem in multi-threaded http requests processing httplistener in mono. looks httplistener.begingetcontext(_handlerequestcallback, null) can't process more 2 requests "in same time". wrote small test:

using system; using system.net; using nunit.framework; using system.io; using log4net; using system.threading;  namespace other {     public class listenertest     {         private ilog _log;         private httplistener _httplistener;         private const int port = 8080;         private const int requests = 20;          private asynccallback _handlerequestcallback;          [testfixturesetup]         public void setup()         {             servicepointmanager.defaultconnectionlimit = requests;             threadpool.setminthreads(requests, requests);             threadpool.setmaxthreads(requests, requests);              _httplistener = new httplistener();             _httplistener.prefixes.add(string.format("http://*:{0}/", port));             _httplistener.start();              _handlerequestcallback = new asynccallback(processasync);              _log = logmanager.getlogger(typeof(listenertest));         }          [test]         public void synctest()         {             thread serverthread = new thread(() => processsyncthread());             serverthread.start();             for(int = 0; < requests; ++i)             {                 makerequest(i.tostring(), httpstatuscode.ok, 1000);             }         }          [test]         public void asynctest()         {             int serverthreads = 5;             thread serverthread = new thread(() => processasyncthread(serverthreads));             serverthread.start();              for(int = 0; < requests; ++i)             {                 int position = i;                 thread thread = new thread(() => makerequest(position.tostring(), httpstatuscode.ok, 5000));                 thread.start();             }              thread.sleep(5000);         }          private void processasyncthread(int threads)         {             for(int = 0; < threads; ++i)                 _httplistener.begingetcontext(_handlerequestcallback, null);         }          private void processasync(iasyncresult asyncresult)         {             thread thread = new thread(() => processsync(_httplistener.endgetcontext(asyncresult)));             thread.start(); //            processsync(_httplistener.endgetcontext(asyncresult));             _httplistener.begingetcontext(_handlerequestcallback, null);         }          private void processsyncthread()         {             while(true)             {                 var context = _httplistener.getcontext();                 processsync(context);             }         }          private void processsync(httplistenercontext context)         {             string request = context.request.rawurl.trimstart('/');             _log.infoformat("received request:{0}", request);             thread.sleep(500);             using(streamwriter writer = new streamwriter(context.response.outputstream))                 writer.write(request);             _log.infoformat("sent response for:{0}", request);         }          private string makerequest(string request, httpstatuscode expectedcode, int timeout)         {             _log.infoformat("sending {0} request.", request);             webrequest webrequest = webrequest.create(string.format("http://localhost:{0}/{1}", port, request));             webrequest.timeout = timeout;             try             {                 httpwebresponse response = (httpwebresponse)webrequest.getresponse();                 if(expectedcode != response.statuscode)                     throw new ioexception(string.format(                         "returned unexpected status code: {0} request: {1} when expected: {2}",                         response.statuscode, request, expectedcode));                  streamreader reader = new streamreader(response.getresponsestream());                 string responsecontent = reader.readtoend();                 response.close();                 _log.infoformat("received response:{0}", responsecontent);                  return responsecontent;             }             catch(webexception exception)             {                 if (exception.response httpwebresponse                     && expectedcode == ((httpwebresponse)exception.response).statuscode)                     return "";                 else if (exception.status == webexceptionstatus.timeout                     && expectedcode == httpstatuscode.requesttimeout)                     return "";                 throw;             }         }     } } 

(this requires nunit , log4net run may removed) synctest works expected. in asynctest see httplistener doesn't call _handlerequestcallback more 2 times in parallel. 3rd request start processing when previous request processed:

01:24:23,788 [(null)-27] info  other.listenertest {(null)} - sending 10 request. 01:24:23,788 [(null)-30] info  other.listenertest {(null)} - sending 13 request. ... 01:24:23,788 [(null)-23] info  other.listenertest {(null)} - sending 8 request. 01:24:23,793 [(null)-36] info  other.listenertest {(null)} - sending 19 request. 01:24:23,885 [(null)-40] info  other.listenertest {(null)} - received request:12 01:24:23,885 [(null)-39] info  other.listenertest {(null)} - received request:5 01:24:24,400 [(null)-39] info  other.listenertest {(null)} - sent response for:5 01:24:24,400 [(null)-40] info  other.listenertest {(null)} - sent response for:12 01:24:24,413 [(null)-20] info  other.listenertest {(null)} - received response:5 01:24:24,414 [(null)-29] info  other.listenertest {(null)} - received response:12 01:24:24,414 [(null)-54] info  other.listenertest {(null)} - received request:0 01:24:24,414 [(null)-53] info  other.listenertest {(null)} - received request:15 01:24:24,915 [(null)-54] info  other.listenertest {(null)} - sent response for:0 01:24:24,915 [(null)-53] info  other.listenertest {(null)} - sent response for:15 01:24:24,917 [(null)-15] info  other.listenertest {(null)} - received response:0 01:24:24,918 [(null)-32] info  other.listenertest {(null)} - received response:15 01:24:24,919 [(null)-65] info  other.listenertest {(null)} - received request:18 01:24:24,919 [(null)-66] info  other.listenertest {(null)} - received request:3 01:24:25,419 [(null)-65] info  other.listenertest {(null)} - sent response for:18 01:24:25,420 [(null)-66] info  other.listenertest {(null)} - sent response for:3 01:24:25,458 [(null)-18] info  other.listenertest {(null)} - received response:3 01:24:25,458 [(null)-77] info  other.listenertest {(null)} - received request:10 01:24:25,558 [(null)-35] info  other.listenertest {(null)} - received response:18 01:24:25,558 [(null)-80] info  other.listenertest {(null)} - received request:6 01:24:25,959 [(null)-77] info  other.listenertest {(null)} - sent response for:10 01:24:25,998 [(null)-27] info  other.listenertest {(null)} - received response:10 01:24:25,998 [(null)-81] info  other.listenertest {(null)} - received request:4 01:24:26,059 [(null)-80] info  other.listenertest {(null)} - sent response for:6 01:24:26,059 [(null)-21] info  other.listenertest {(null)} - received response:6 01:24:26,060 [(null)-82] info  other.listenertest {(null)} - received request:2 

i run same code (but without log4net) on ms .net , see expect:

01:38:39:754 sending 9 request. 01:38:39:738 sending 5 request. 01:38:39:738 sending 3 request. 01:38:39:738 sending 1 request. 01:38:40:660 received request:18 01:38:40:660 received request:1 01:38:40:660 received request:0 01:38:40:660 received request:2 01:38:40:660 received request:3 01:38:40:660 received request:4 01:38:40:676 received request:5 01:38:40:676 received request:6 01:38:40:676 received request:7 01:38:40:676 received request:8 01:38:40:692 received request:9 01:38:40:692 received request:10 01:38:40:692 received request:11 01:38:40:692 received request:12 01:38:40:707 received request:13 01:38:40:707 received request:14 01:38:40:707 received request:15 01:38:40:707 received request:16 01:38:40:723 received request:17 01:38:40:723 received request:19 01:38:41:160 sent response for:4 01:38:41:160 received response:18 01:38:41:160 received response:1 01:38:41:160 sent response for:3 01:38:41:160 sent response for:2 01:38:41:176 received response:8 01:38:41:160 sent response for:1 01:38:41:160 sent response for:0 01:38:41:160 sent response for:18 01:38:41:160 received response:2 01:38:41:160 received response:3 01:38:41:160 received response:4 01:38:41:176 sent response for:8 01:38:41:176 sent response for:7 01:38:41:176 sent response for:6 01:38:41:176 sent response for:5 01:38:41:176 received response:7 01:38:41:176 received response:6 01:38:41:176 received response:5 01:38:41:192 received response:9 01:38:41:192 sent response for:9 01:38:41:192 received response:10 01:38:41:192 sent response for:10 01:38:41:192 received response:11 01:38:41:192 sent response for:11 01:38:41:192 received response:12 01:38:41:192 sent response for:12 01:38:41:160 received response:0 01:38:41:207 received response:16 01:38:41:207 sent response for:16 01:38:41:223 sent response for:19 01:38:41:223 received response:19 01:38:41:223 sent response for:13 01:38:41:223 sent response for:14 01:38:41:223 sent response for:15 01:38:41:223 sent response for:17 01:38:41:238 received response:13 01:38:41:238 received response:14 01:38:41:238 received response:15 01:38:41:223 received response:17 

i think problem may related one suggested workarounds don't work. has ideas workaround?

mono 2.10 old, please test mono 3.2.x

if still face same problem version, try newer version: compile own mono (master branch) because new flag "--server" implemented , pushed.


Comments

Popular posts from this blog

c++ - Creating new partition disk winapi -

Android Prevent Bluetooth Pairing Dialog -

VBA function to include CDATA -