Add async API's for caching
Provide async overloads for caching API so async operations can construct the cache.
More info:
http://stackoverflow.com/questions/20505186/servicestack-v4-server-side-async
This has now been implemented as part of the major async upgrade in v5.10 release:
-
Anonymous commented
Yes please. I just hit this problem too. Used Alex's response below.
-
Alex Palma commented
I wanted this also and since there was nothing still, I decided to created my own extension methods to perform this. Remember this needs .net framework 4.5, or PCL that targets that.
using System;
using System.Threading.Tasks;
using ServiceStack.Caching;
using ServiceStack.Web;
namespace ServiceStack
{
public static class CacheClientAsyncExtensions
{
/// <summary>
/// Overload for the <see cref="!:ContentCacheManager.Resolve" /> method returning the most
/// optimized result based on the MimeType and CompressionType from the IRequestContext.
/// </summary>
public static async Task<object> ToOptimizedResultUsingCacheAsync<T>(this IRequest requestContext,
ICacheClient cacheClient,
string cacheKey,
Func<Task<T>> factoryAsyncFn)
{
return await ToOptimizedResultUsingCacheAsync(requestContext, cacheClient, cacheKey, null, factoryAsyncFn);
}
/// <summary>
/// Overload for the <see cref="!:ContentCacheManager.Resolve" /> method returning the most
/// optimized result based on the MimeType and CompressionType from the IRequestContext.
/// <param name="expireCacheIn">How long to cache for, null is no expiration</param>
/// </summary>
public static async Task<object> ToOptimizedResultUsingCacheAsync<T>(this IRequest requestContext,
ICacheClient cacheClient,
string cacheKey,
TimeSpan? expireCacheIn,
Func<Task<T>> factoryAsyncFn)
{
return cacheClient.ResolveFromCache(cacheKey, requestContext) ??
cacheClient.Cache(cacheKey, await factoryAsyncFn(), requestContext, expireCacheIn);
}
public static async Task<T> GetOrCreateAsync<T>(this ICacheClient cache, string key, Func<Task<T>> createAsyncFn)
{
var obj = cache.Get<T>(key);
if (!Equals(obj, default (T)))
{
return obj;
}
obj = await createAsyncFn();
cache.Set(key, obj);
return obj;
}
public static async Task<T> GetOrCreate<T>(this ICacheClient cache,
string key,
TimeSpan expiresIn,
Func<Task<T>> createAsyncFn)
{
var obj = cache.Get<T>(key);
if (!Equals(obj, default (T)))
{
return obj;
}
obj = await createAsyncFn();
cache.Set(key, obj, expiresIn);
return obj;
}
}
}
}
Now to use it we can just do.
var cacheKey = "MyCacheKey";
return Request.ToOptimizedResultUsingCacheAsync(Cache,
cacheKey,
async () => await businessObject.MyMethodAsync());
and voila now we have a ToOptimizedResultUsingCacheAsync method that can be used with async services.