asynchronous - Correct way to convert method to async in C#? -


i'm attempting convert following method (simplified example) asynchronous, cachemissresolver call may expensive in terms of time (database lookup, network call):

// synchronous version public class thingcache {     private static readonly object _lockobj;     // ... other stuff      public thing get(string key, func<thing> cachemissresolver)     {         if (cache.contains(key))             return cache[key];          thing item;          lock(_lockobj)         {             if (cache.contains(key))                 return cache[key];              item = cachemissresolver();                 cache.add(key, item);         }          return item;     } } 

there plenty of materials on-line consuming async methods, advice have found on producing them seems less clear-cut. given intended part of library, either of attempts below correct?

// asynchronous attempts public class thingcache {     private static readonly semaphoreslim _lockobj = new semaphoreslim(1);     // ... other stuff      // attempt #1     public async task<thing> get(string key, func<thing> cachemissresolver)     {         if (cache.contains(key))             return await task.fromresult(cache[key]);          thing item;          await _lockobj.waitasync();          try         {             if (cache.contains(key))                 return await task.fromresult(cache[key]);              item = await task.run(cachemissresolver).configureawait(false);             _cache.add(key, item);         }                 {             _lockobj.release();         }          return item;     }      // attempt #2     public async task<thing> get(string key, func<task<thing>> cachemissresolver)     {         if (cache.contains(key))             return await task.fromresult(cache[key]);          thing item;          await _lockobj.waitasync();          try         {             if (cache.contains(key))                 return await task.fromresult(cache[key]);              item = await cachemissresolver().configureawait(false);             _cache.add(key, item);         }                 {             _lockobj.release();         }          return item;     } } 

is using semaphoreslim correct way replace lock statement in async method? (i can't await in body of lock statement.)

should make cachemissresolver argument of type func<task<thing>> instead? although puts burden of making sure resolver func async on caller (wrapping in task.run, know offloaded background thread if takes long time).

thanks.

is using semaphoreslim correct way replace lock statement in async method?

yes.

should make cachemissresolver argument of type func<task<thing>> instead?

yes. it'll allow caller provide inherently asynchronous operation (such io) rather making suitable work long running cpu bound work. (while still supporting cpu bound work having caller use task.run themselves, if that's want do.)


other that, note there's not point in having await task.fromresult(...); wrapping value in task unwrap pointless. use result directly in such situations, in case, return cached value directly. you're doing isn't wrong, it's needlessly complicating/confusing code.


Comments

Popular posts from this blog

javascript - Bootstrap Popover: iOS Safari strange behaviour -

Website Login Issue developed in magento -

Can the constants be defined inside a model file of a framework in PHP? -