c# - Multiple callers waiting on long running GET, any way to make them all wait on the same return? -
i running wcf rest service , have discovered bit of bottleneck. current code boils down below:
private static list<widget> widgets; public async task<list<searchresult>> search(string term) { if(widgets == null) { // call takes 60 seconds widgets = await getwidgets(); } return searchutil.search(term, widgets); }
the problem many requests can enter if check , call long running operation. instead, want additional incoming requests wait on original call complete , 1 call getwidgets() made. how can achieve stop firing off many requests when dictionary empty?
as small aside, safe assume list/dictionary remain populated entire time service alive? or empty reason? best way handle type of situation (i'm guessing other mechanism cache)?
thanks!
if understand correctly, want cache never expires , populated first time requests value. should pretty straightforward build in generic way:
class nonexpiringlazyloadingcache<t> { private readonly func<task<t>> _factory; private task<t> _retrievaltask; private readonly object _lockobject = new object(); public nonexpiringlazyloadingcache(func<task<t>> factory) { this._factory = factory; } public async task<t> getvalue() { lock (this._lockobject) if (this._retrievaltask == null) this._retrievaltask = this._factory(); await this._retrievaltask; return this._retrievaltask.result; } }
key things note task<t>
await
return when task completed, thread safe; task guaranteed executed once.
usage:
private static nonexpiringlazyloadingcache<list<widget>> cache = new nonexpiringlazyloadingcache<list<widget>>(getwidgets); ... var widgets = await cache.getvalue();
as duration of object's lifetime, depends on wcf service hosted. stays long process stays alive, iis hosted services value cleared when application pool recycled.