Ik denk dat je hier in de war raakt. ConnectionMultiplexer
wordt niet "geblokkeerd". Een ConnectionMultiplexer
maken geeft je een fabrieksachtig object waarmee je IDatabase
. kunt maken gevallen. U gebruikt deze instanties vervolgens om normale Redis-query's uit te voeren. Je kunt ook Redis-query's uitvoeren met de verbindingsmultiplexer zelf, maar dat zijn serverquery's en zullen waarschijnlijk niet vaak worden gedaan.
Dus, om het kort te houden, het kan enorm helpen om een pool van verbindingsmultiplexers te hebben, ongeacht de synchronisatie /async/gemengd gebruik.
Om verder uit te breiden, is hier een zeer eenvoudige poolimplementatie, die zeker verder kan worden verbeterd:
public interface IConnectionMultiplexerPool
{
Task<IDatabase> GetDatabaseAsync();
}
public class ConnectionMultiplexerPool : IConnectionMultiplexerPool
{
private readonly ConnectionMultiplexer[] _pool;
private readonly ConfigurationOptions _redisConfigurationOptions;
public ConnectionMultiplexerPool(int poolSize, string connectionString) : this(poolSize, ConfigurationOptions.Parse(connectionString))
{
}
public ConnectionMultiplexerPool(int poolSize, ConfigurationOptions redisConfigurationOptions)
{
_pool = new ConnectionMultiplexer[poolSize];
_redisConfigurationOptions = redisConfigurationOptions;
}
public async Task<IDatabase> GetDatabaseAsync()
{
var leastPendingTasks = long.MaxValue;
IDatabase leastPendingDatabase = null;
for (int i = 0; i < _pool.Length; i++)
{
var connection = _pool[i];
if (connection == null)
{
_pool[i] = await ConnectionMultiplexer.ConnectAsync(_redisConfigurationOptions);
return _pool[i].GetDatabase();
}
var pending = connection.GetCounters().TotalOutstanding;
if (pending < leastPendingTasks)
{
leastPendingTasks = pending;
leastPendingDatabase = connection.GetDatabase();
}
}
return leastPendingDatabase;
}
}