11

Assume i have the following interface:

public interface IApiOutputCache
{
    Task RemoveStartsWithAsync(string key);
    Task<T> Get<T>(string key) where T : class;
    Task RemoveAsync(string key);
    Task<bool> ContainsAsync(string key);
    Task Add(string key, object o, DateTimeOffset expiration, params string[] dependsOnKeys);
    Task<IEnumerable<string>> GetAllKeys();
}

I can implement different cache providers. I implemented it twice for two different caches:

a) azure redis b) memory cache

For azure redis this works absolutely fine since StackExchange.Redis offers all the async methods for me so i can stay completely async.

Now i implement another one for the memory cache which does not offer async api for me. Now what is the best pratice to implement this interface? Implement it as is but just do everything sync? Warp the internal calls to a Task.Run (not a good idea for fast mem cache calls i think).

Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
LaurinSt
  • 952
  • 11
  • 25
  • I agree with your suggestion. Alternatively, you could run everything synchronously and return Task.FromResult to make it look like it's asynchronous. – hbulens Oct 04 '15 at 10:24

1 Answers1

11

Forget about Task.Run, there's no need to offload anything to the ThreadPool.

Implement everything synchronously and return an already completed Task with Task.FromResult when returning a value and Task.CompletedTask when not:

Task<T> GetAsync<T>(string key)
{
    T result = Get(key);
    return Task.FromResult(result);
}

Task RemoveAsync(string key)
{
    Remove(key);
    return Task.CompletedTask;
}

Or even better, since it's a cache you can cache the tasks themselves instead of the results and return the same task object every time.

i3arnon
  • 113,022
  • 33
  • 324
  • 344
  • Thanks. Okey that was the way i supposed. But what is Task.CompletedTask? It is new in .net 4.6 right? how does it differ from Task.FromResult(0)? – LaurinSt Oct 04 '15 at 10:50
  • Yes, it's new in .Net 4.6. It's slightly better because it returns the same instance every time instead of allocating a new task each call. http://stackoverflow.com/a/26226195/885318 – i3arnon Oct 04 '15 at 10:52