c# - Multithread answering for HttpListener -


i have single thread process executes long time. need several users have access execute process , choose http protocol manage invocation.

naturally, when 1 process working else should wait till it's done. if process available executes. if not busy answer sent.

here implementation:

using system; using system.net; using system.reflection; using system.runtime.interopservices; using system.threading; using system.threading.tasks;  namespace simplehttp {     class program     {         private static system.asynccallback task;         private static system.threading.manualresetevent mre = new system.threading.manualresetevent(false);// notifies 1 or more waiting threads event has occurred.          private static httplistenercontext workingcontext = null;          public static bool isbackgroundworking()         {             return mre.waitone(0);         }         static void main(string[] args)         {             new thread(() =>             {                 thread.currentthread.isbackground = true;                 while (true)                 {                     console.writeline("    waitone " + isbackgroundworking());                     mre.waitone(); // blocks current thread until current waithandle receives signal.                     console.writeline("    job" + " [" + thread.currentthread.name + ":" + thread.currentthread.managedthreadid + " ]\n");                     httplistenerrequest request = workingcontext.request;                     httplistenerresponse response = workingcontext.response;                     string responsestring = "work " + datetime.now ;                     byte[] buffer = system.text.encoding.utf8.getbytes(responsestring);                     response.contentlength64 = buffer.length;                     system.io.stream output = response.outputstream;                     thread.sleep(10000);                     output.write(buffer, 0, buffer.length);                     output.close();                     console.writeline("    " + responsestring + "\t" + datetime.now);                     workingcontext = null;                     mre.reset(); // sets state of event nonsignaled, causing threads block.                 }             }).start();              // create listener.             httplistener listener = new httplistener();              listener.prefixes.add("http://localhost:6789/index/");             listener.start();             console.writeline("listening..." + " [" + thread.currentthread.name + ":" + thread.currentthread.managedthreadid + " ]\n");              task = new asynccallback(listenercallback);              iasyncresult resultm = listener.begingetcontext(task,listener);             console.writeline("waiting request processed asyncronously.");              console.readkey();             console.writeline("request processed asyncronously.");             listener.close();         }          private static void listenercallback(iasyncresult result)         {             httplistener listener = (httplistener) result.asyncstate;              //if not listening return method called 1 last time after close()             if (!listener.islistening)                 return;              httplistenercontext context = listener.endgetcontext(result);             listener.begingetcontext(task, listener);              if (workingcontext == null && !isbackgroundworking())             {                 // background work                 workingcontext = context;                 mre.set(); //sets state of event signaled, allowing 1 or more waiting threads proceed.             }             else             {             httplistenerrequest request = context.request;             httplistenerresponse response = context.response;             string responsestring = "busy "+ datetime.now + " [" + thread.currentthread.name + ":" + thread.currentthread.managedthreadid;             byte[] buffer = system.text.encoding.utf8.getbytes(responsestring);             response.contentlength64 = buffer.length;             system.io.stream output = response.outputstream;             output.write(buffer, 0, buffer.length);             output.close();             console.writeline(responsestring + "\t" + datetime.now);             }         }     } } 

to test 2 http calls. expect have 2 different answers work , busy. see second request waits first finish , executes.

      waitone false listening... [:10 ]  waiting request processed asyncronously.       job [:11 ]        work 1/24/2016 10:34:01  1/24/2016 10:34:11       waitone false       job [:11 ]        work 1/24/2016 10:34:11  1/24/2016 10:34:21       waitone false 

what wrong in understanding how should work?

update (too many comments not ecouraged so): code looks awkward because replication of real process. in "my" application working process main process has has "courtesy" run embedded c# code @ particular moments. so, cannot run new task process request , must asyncronious since working process own job , invokes slave piece of code notify clients when data available. asyncroinious because code invoked , should finish possible or block master application. i'll try add additional thread synchronous call , see hot affects situation.

debugger not used in example not interfere real time process , time stamps printed console. debugging great , necessary in case try substitute output avoid actor in synchronization/waiting scenario.

the application not heavy loaded conversation. 1-3 clients seldom ask main application answer. http protocol used convenience not heavy or conversations. appears browsers ie work fine (windows windows conversation?) , chrome (more system agnostic) replicate application behavior. @ time stamps, chrome, ie,ie,chrome , last chrome still went work process. btw, code changed per conversation suggestion , new request placed after retrieving previous one.

    httplistenercontext context = listener.endgetcontext(result);     listener.begingetcontext(task, listener);  

enter image description here

also, following suggestions, had change asyncronious call syncroniuos , result still same

private static void listenercallback(iasyncresult result) {     httplistener listener = (httplistener) result.asyncstate;      //if not listening return method called 1 last time after close()     if (!listener.islistening)         return;      httplistenercontext context = listener.endgetcontext(result);      while (true)     {         if (workingcontext == null && !isbackgroundworking())         {             // background work             workingcontext = context;             mre.set(); //sets state of event signaled, allowing 1 or more waiting threads proceed.         }         else         {             httplistenerrequest request = context.request;             httplistenerresponse response = context.response;             string responsestring = "busy " + datetime.now + " [" + thread.currentthread.name + ":" +                                     thread.currentthread.managedthreadid;             byte[] buffer = system.text.encoding.utf8.getbytes(responsestring);             response.contentlength64 = buffer.length;             system.io.stream output = response.outputstream;             output.write(buffer, 0, buffer.length);             output.close();             console.writeline(responsestring + "\t" + datetime.now);         }         context=listener.getcontext();     } } 

the code posted works should:

enter image description here

can't reproduce. guess answers question because apparently you're driving test workload incorrectly. drove repeatedly clicking fiddler composer send button.

thanks posting executable code, though. should have tried earlier!


Comments