使用Redis Pub / Sub使用ChangeMonitor使内存缓存无效

时间:2016-10-08 17:19:32

标签: c# redis stackexchange.redis

我创建了一个新类,用于使Memory Cached数据无效并从Redis加载新的数据副本。 它还取决于Redis的发布/子功能。

public class RedisChangeMonitor : ChangeMonitor
{
    private string uniqueId;
    private ISubscriber subscriber;

    private static Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() =>
    {
        ConnectionMultiplexer connectionMultiplexer = ConnectionMultiplexer.Connect(ConfigurationManager.ConnectionStrings["RedisConnectionString"].ConnectionString);
        connectionMultiplexer.PreserveAsyncOrder = false;
        return connectionMultiplexer;
    });

    public ConnectionMultiplexer Connection
    {
        get
        {
            return lazyConnection.Value;
        }
    }

    public override string UniqueId
    {
        get
        {
            return uniqueId;
        }
    }

    public RedisChangeMonitor(IList<string> cacheKeys)
    {
        bool isInitialized = false;
        try
        {
            this.uniqueId = Guid.NewGuid().ToString();

            subscriber = this.Connection.GetSubscriber();
            subscriber.Subscribe(RedisChannels.ChangeNotification, (channel, data) =>
            {
                string cacheKey = data;
                if (cacheKeys.Contains(cacheKey))
                {
                    base.OnChanged(null);
                }
            });
            isInitialized = true;
        }
        finally
        {
            base.InitializationComplete();
            if (!isInitialized)
                Dispose(true);
        }
    }

    ~RedisChangeMonitor()
    {
        Dispose(false);
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            if (subscriber != null)
            {
                subscriber.Unsubscribe(RedisChannels.ChangeNotification);
            }
        }
    }
}

我在ASP.NET MVC App中使用过这个类,我已经看到,如果我没有在dispose方法中取消订阅,服务器的内存在大约1小时后就已满了。

如果我在Dispose方法中取消订阅,则内存状态正常。但是内存缓存没有失效。

1 个答案:

答案 0 :(得分:0)

看起来您正在为每个实例订阅,但您对取消订阅的使用目前并未通过代理,因此&#34;取消订阅所有人&#34;。

您应该将lambda移动到本地方法,并将兼容的委托传递给subscribe和unsubscribe。