And the new version with C# Asynchronous Streaming via IAsyncEnumerable
available in Redis.StackExchange v2.1.0-preview.23 and above.
NOTE: this version uses SCAN instead of KEYS if your Redis Instance supports that feature. This is a huge performance boost. You should also make sure your instance of ConnectionMultiplexer
is a singleton - i.e. same instance used for the lifetime of the app.
I should also callout that Redis wildcard support allows for pretty flexible patterns. In my implementation (below), I only had a need to have a '*' at the end of the key, so that is all it is coded for. If you need additional wildcard support, you can implement the Redis wildcard supported glob-style patterns here:
- h?llo matches hello, hallo and hxllo
- h*llo matches hllo and heeeello
- h[ae]llo matches hello and hallo, but not hillo
- h[^e]llo matches hallo, hbllo, ... but not hello
- h[a-b]llo matches hallo and hbllo
Use \ to escape special characters if you want to match them verbatim.
using Microsoft.Extensions.Caching.Distributed;
using StackExchange.Redis;
private readonly IDistributedCache _cache;
private readonly IConnectionMultiplexer _connectionMultiplexer;
public CacheRepository(IDistributedCache cache, IConnectionMultiplexer connectionMultiplexer)
{
_cache = cache;
_connectionMultiplexer = connectionMultiplexer;
}
public async Task RemoveWithWildCardAsync(string keyRoot)
{
if (string.IsNullOrWhiteSpace(keyRoot))
throw new ArgumentException("Value cannot be null or whitespace.", nameof(keyRoot));
// get all the keys* and remove each one
await foreach (var key in GetKeysAsync(keyRoot + "*"))
{
await _cache.RemoveAsync(key);
}
}
public async IAsyncEnumerable<string> GetKeysAsync(string pattern)
{
if (string.IsNullOrWhiteSpace(pattern))
throw new ArgumentException("Value cannot be null or whitespace.", nameof(pattern));
foreach (var endpoint in _connectionMultiplexer.GetEndPoints())
{
var server = _connectionMultiplexer.GetServer(endpoint);
await foreach (var key in server.KeysAsync(pattern: pattern))
{
yield return key.ToString();
}
}
}
public IEnumerable<RedisFeatures> GetRedisFeatures()
{
foreach (var endpoint in _connectionMultiplexer.GetEndPoints())
{
var server = _connectionMultiplexer.GetServer(endpoint);
yield return server.Features;
}
}