c# - How to prevent HttpListener from aborting pending requests on stoppage? HttpListener.Stop is not working -
i have problem here. in below code async/await pattern used httplistener. when request sent via http "delay" query string argument expected , value causes server delay mentioned request processing given period. need server process pending requests after server stopped receiving new requests.
static void main(string[] args) { httplistener httplistener = new httplistener(); countdownevent sessions = new countdownevent(1); bool stoprequested = false; httplistener.prefixes.add("http://+:9000/getdata/"); httplistener.start(); task listenertask = task.run(async () => { while (true) { try { var context = await httplistener.getcontextasync(); sessions.addcount(); task childtask = task.run(async () => { try { console.writeline($"request accepted: {context.request.rawurl}"); int delay = int.parse(context.request.querystring["delay"]); await task.delay(delay); using (streamwriter sw = new streamwriter(context.response.outputstream, encoding.default, 4096, true)) { await sw.writeasync("<html><body><h1>hello world</h1></body></html>"); } context.response.close(); } { sessions.signal(); } }); } catch (httplistenerexception ex) { if (stoprequested && ex.errorcode == 995) { break; } throw; } } }); console.writeline("server running. enter stop..."); console.readline(); sessions.signal(); stoprequested = true; httplistener.stop(); console.writeline("stopped accepting requests. waiting pendings..."); listenertask.wait(); sessions.wait(); console.writeline("finished"); console.readline(); httplistener.close(); }
the exact problem here, when server stopped httplistener.stop called, pending requests aborted immediately, i.e. code unable send responses back.
in non-async/await pattern (i.e. simple thread based implementation) have choice abort thread (which suppose bad) , allow me process pending requests, because aborts httplistener.getcontext call.
can please point me out, doing wrong , how can prevent httplistener abort pending requests in async/await pattern?
it seems when httplistener
closes request queue handle, requests in progress aborted. far can tell, there no way avoid having httplistener
- apparently, it's compatibility thing. in case, that's how getcontext
-ending system works - when handle closed, native method getcontext
call request context returns error immediately.
thread.abort
doesn't - really, i've yet see place thread.abort
used correctly outside of "application domain unloading" scenario. thread.abort
can ever abort managed code. since code running native, aborted when returns managed code - equivalent doing this:
var context = await httplistener.getcontextasync(); if (stoprequested) return;
... , since there's no better cancellation api httplistener
, option if want stick httplistener
.
the shutdown this:
stoprequested = true; sessions.wait(); httplistener.dispose(); listenertask.wait();
i'd suggest using cancellationtoken
instead of bool
flag - handles synchronization woes you. if that's not desirable reason, make sure synchronize access flag - contractually, compiler allowed omit check, since it's impossible flag change in single-threaded code.
if want to, can make listenertask
complete sooner sending dummy http request right after setting stoprequested
- cause getcontext
return new request, , can return. approach that's commonly used when dealing apis don't support "nice" cancellation, e.g. udpclient.receive
.
Comments
Post a Comment