Reputation: 51
I have created a new class that will be used to invalidate the Memory Cached data and load new Copy of the data from Redis. Also it depends on the pub/sub feature of 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);
}
}
}
}
I used this class in ASP.NET MVC App, i have seen that the memory of the server is full after around 1 hour if i didn't unsubscribe in the dispose method.
If i have unsubscribed in the Dispose method, the memory status is ok. But the Memory Cache is not invalidated.
Upvotes: 1
Views: 971
Reputation: 1062492
It looks like you're subscribing per instance, but your usage of unsubscribe currently doesn't pass in a delegate, and is therefore "unsubscribe everyone".
You should move the lambda to a local method and pass a compatible delegate to both subscribe and unsubscribe.
Upvotes: 0