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);
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:
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
Post a Comment