/// <summary> /// Execute the given query as an synchronous operation. /// </summary> /// <param name="query">The query to be executed</param> /// <param name="options">Query options to use for this query</param> /// <returns>The result of the given query</returns> public TResult QuerySync(TQuery query, EntryOptions options) { if ((options.Behaviors & EntryBehaviors.LookupCache) == EntryBehaviors.LookupCache) { if ((options.Behaviors & EntryBehaviors.SaveToCache) == EntryBehaviors.SaveToCache) { return(m_queryTaskCache.GetOrAdd(query, new Lazy <TResult>(() => DoQuerySync(query)), options).Value); } else { Lazy <TResult> lazyResult; if (m_queryTaskCache.TryGet(query, out lazyResult)) { return(lazyResult.Value); } else { return(DoQuerySync(query)); } } } else { if ((options.Behaviors & EntryBehaviors.SaveToCache) == EntryBehaviors.SaveToCache) { var newQueryTask = new Lazy <TResult>(() => DoQuerySync(query)); m_queryTaskCache.Set(query, newQueryTask, options); return(newQueryTask.Value); } else { return(DoQuerySync(query)); } } }
/// <summary> /// Execute the given query as an asynchronous operation with a specified cache policy. /// </summary> /// <param name="query">The query to be executed</param> /// <param name="options">The cache policy options.</param> /// <returns>The task object representing the asynchronous operation</returns> public Task <TResult> QueryAsync(TQuery query, EntryOptions options) { Task <TResult> queryTask = null; if ((options.Behaviors & EntryBehaviors.LookupCache) == EntryBehaviors.LookupCache) { if ((options.Behaviors & EntryBehaviors.SaveToCache) == EntryBehaviors.SaveToCache) { queryTask = m_queryTaskCache.GetOrAdd(query, new AsyncLazy <TResult>(() => DoQueryAsync(query)), options).Value; } else { AsyncLazy <TResult> asyncLazyResult; if (m_queryTaskCache.TryGet(query, out asyncLazyResult)) { queryTask = asyncLazyResult.Value; } else { //no task cached, do it directly return(DoQueryAsync(query)); } } //re-query if the task is canceld or failed. if ((queryTask.IsFaulted || queryTask.IsCanceled) && (options.Behaviors & EntryBehaviors.ReQueryWhenErrorCached) == EntryBehaviors.ReQueryWhenErrorCached) { options.Behaviors ^= EntryBehaviors.LookupCache; this.QueryAsync(query, options); } //query is cached, just await the result return(queryTask); } else { if ((options.Behaviors & EntryBehaviors.SaveToCache) == EntryBehaviors.SaveToCache) { var newQueryTask = new AsyncLazy <TResult>(() => DoQueryAsync(query)); m_queryTaskCache.Set(query, newQueryTask, options); return(newQueryTask.Value); } else { return(DoQueryAsync(query)); } } }