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

Popular posts from this blog

Ansible - ERROR! the field 'hosts' is required but was not set -

customize file_field button ruby on rails -

SoapUI on windows 10 - high DPI/4K scaling issue -