0

I've been working with ObjectCache for some time and I've been having some problems with users getting logged out after some use.

What is happening that the ObjectCache is clearing the Cache after some refreshes in the browser, it's happening in my machine, developer, and in the production application.

This is my class (all of it):

using System;
using System.Runtime.Caching;

namespace autoSCORE.Utilidade.GerenciadorCache
{
    /// <summary>
    /// Gerencia a Criação, Atualização e Exclusão de Cache.
    /// </summary>
    /// <typeparam name="T">Objeto, do tipo <see cref="T"/>, preenchido com o Tipo de Conteúdo a ser guardado no Cache.</typeparam>
    public static class Cache<T> where T : class
    {
        /// <summary>
        /// Singleton do objeto, do tipo <see cref="System.Runtime.Caching.ObjectCache"/>.
        /// </summary>
        private static ObjectCache memoryCache = MemoryCache.Default;
        /// <summary>
        /// objeto, do tipo <see cref="System.Runtime.Caching.CacheItemPolicy"/>., com as Políticas do Cache.
        /// </summary>
        private static CacheItemPolicy cacheItemPolicy = null;

        /// <summary>
        /// Cria o Cache do Item desejado.
        /// </summary>
        /// <param name="chave">Objeto, do tipo <see cref="System.String"/>, preenchido com a Chave desejada.</param>
        /// <param name="conteudo">Objeto, do tipo <see cref="T"/>, preenchido com o Conteudo desejado.</param>
        /// <param name="persistir">Objeto, do tipo <see cref="System.Boolean"/>, preenchido com "True", para extender por 10 dias, ou "False", para extender por 60 minutos.</param>
        public static void Adicionar(string chave, T conteudo, bool persistir)
        {
            try
            {
                cacheItemPolicy = new CacheItemPolicy();
                cacheItemPolicy.Priority = CacheItemPriority.Default;
                cacheItemPolicy.SlidingExpiration = persistir ? new TimeSpan(10, 0, 0, 0) : new TimeSpan(1, 0, 0);

                memoryCache.Set(chave, conteudo, cacheItemPolicy);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// Retorna o Item, do Cache, desejado.
        /// </summary>
        /// <param name="chave">Objeto, do tipo <see cref="System.String"/>, preenchido com a Chave desejada.</param>
        /// <returns>Objeto, do tipo <see cref="T"/>, preenchido com o Conteudo recuperado.</returns>
        public static T Recuperar(string chave)
        {
            try
            {
                if (memoryCache.Contains(chave))
                {
                    var objectT = (T)memoryCache[chave];

                    if (objectT == null) return default(T);

                    System.Reflection.MethodInfo newInstanceOfObjectT =
                        objectT.GetType().GetMethod("MemberwiseClone", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);

                    if (newInstanceOfObjectT == null) return default(T);

                    return (T)newInstanceOfObjectT.Invoke(objectT, null);
                }
                else
                {
                    return default(T);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// Atualiza o Item, no Cache, desejado.
        /// </summary>
        /// <param name="chave">Objeto, do tipo <see cref="System.String"/>, preenchido com a Chave desejada.</param>
        /// <param name="novoConteudo">Objeto, do tipo <see cref="T"/>, preenchido com o novo Conteudo desejado.</param>
        public static void Atualizar(string chave, T novoConteudo)
        {
            try
            {
                if (memoryCache.Contains(chave))
                {
                    var content = (T)memoryCache[chave];

                    content = novoConteudo;

                    memoryCache[chave] = content;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }

        /// <summary>
        /// Remove o Item desejado.
        /// </summary>
        /// <param name="chave">Objeto, do tipo <see cref="System.String"/>, preenchido com a Chave desejada.</param>
        public static void Remover(string chave)
        {
            try
            {
                if (memoryCache.Contains(chave))
                {
                    memoryCache.Remove(chave);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }
    }
}

Thanks and Best Regards, Rodrigo Lemela Duarte

Rob Lyndon
  • 12,089
  • 5
  • 49
  • 74
  • 3
    Could it be the fact that the IIS AppPool is refreshing itself every 20 minutes or so (and thus clearing any memory cache objects)? It's hard to tell how you're using this, but bear in mind that any object cache like this should be self-healing (e.g., get the item from cache, if it doesn't exist, regenerate from and cache it for the next call). Also note that session information is something else altogether... – jleach Dec 27 '16 at 23:00
  • Everything that @jdl134679 said, plus this: if you're storing a huge amount of information in the MemoryCache, it might be hitting a limit: https://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache.cachememorylimit(v=vs.110).aspx – Nate Barbettini Dec 27 '16 at 23:02
  • How do you call `Adicionar` method ? – CodeNotFound Dec 27 '16 at 23:10
  • @jdl134679, I really don't know if it's IIS AppPool refreshing itself, because only happen this when the user refreshs many time the browser... The cache can't be self-healing because of business rules in it. – BetaSystems - Rodrigo Duarte Dec 28 '16 at 20:09
  • @NateBarbettini All the data set in the cache are small, only the user information, and this is happening in my local machine and in my server, so, the amount of data is irrelevant. – BetaSystems - Rodrigo Duarte Dec 28 '16 at 20:10
  • @CodeNotFound ´Utilidade.GerenciadorCache.Cache.Adicionar(conteudo, dtoUsuario, persistente);´; ´conteudo´ is the content that I will add in cache, ´dtoUsuario´ is the User DTO and ´persistente´ is a boolean. – BetaSystems - Rodrigo Duarte Dec 28 '16 at 20:12

0 Answers0