asp.net - C# allowing one thread to run the method at a time after multiple requests triggerred to application server -
i building asp.net web.api service. there api needs more 2 minutes retrieve desired data, implemented cache mechanism, , every request sent api server, server return cached data , meanwhile start new thread load new data cache, issue if submitted lot of requests, lot of thread running , crashed server, want implement mechanism control thread @ time, know asp.net web.api inherently multi threads, how tell other request wait, because there 1 thread retrieving new set of data ?
[dependency] public icachemanager<orderarray> orderarraycache { get; set; } private readorderservice service = new readorderservice(); private const string _ckey = "all"; public dynamic get() { try { orderarray cache = orderarraycache.get(_ckey); if(cache == null || cache.orders.length == 0) { orderarray data = service.getallorders(); orderarraycache.add(_ckey, data); return data; } else { caching(); return cache; } } catch (exception error) { errorlog.writelog(config._systemname, this.gettype().name, system.reflection.methodbase.getcurrentmethod().name, error.tostring()); return 0; } } public void caching() { thread worker = new thread(() => cacheworker()); worker.start(); } public void cacheworker() { try { //activitylog.writelog(config._systemname, this.gettype().name, system.reflection.methodbase.getcurrentmethod().name, "cache worker starting work"); orderarray data = service.getallorders(); orderarraycache.put(_ckey, data); //activitylog.writelog(config._systemname, this.gettype().name, system.reflection.methodbase.getcurrentmethod().name, "cache worker working hard"); } catch(exception error) { //activitylog.writelog(config._systemname, this.gettype().name, system.reflection.methodbase.getcurrentmethod().name, error.tostring()); } }
without commenting on overall architecture, it's trivial setting flag you're working, , not starting thread if flag set.
of course in asp.net mvc/webapi context, controller instance created every request, simple field won't work. make static, that'll work per appdomain: 1 application can run in multiple appdomains, using multiple worker processes.
you solve using mutex, application in server farm, introducing whole shebang of new problems.
that being said, naive, static approach:
private static bool _currentlyretrievingcacheabledata = false; public void caching() { if (_currentlyretrievingcacheabledata) { return; } thread worker = new thread(() => cacheworker()); worker.start(); } public void cacheworker() { try { _currentlyretrievingcacheabledata = true; // ... } catch(exception error) { // ... } { _currentlyretrievingcacheabledata = false; } }
there's still race issue here, @ 2 threads can accessing cacheworker()
method. can prevent using lock
statement.
do note of workarounds doing obvious: let cache refreshing mechanism live outside web application code, example in windows service or scheduled task.
Comments
Post a Comment