Penso che ti stai confondendo qui. ConnectionMultiplexer
non "si blocca". Creazione di un ConnectionMultiplexer
ti dà un oggetto simile a una fabbrica con cui puoi creare IDatabase
istanze. Quindi puoi utilizzare queste istanze per eseguire normali query Redis. Puoi anche eseguire query Redis con il multiplexer di connessione stesso, ma si tratta di query sul server ed è improbabile che vengano eseguite spesso.
Quindi, per farla breve, può essere di grande aiuto avere un pool di multiplexer di connessione, indipendentemente dalla sincronizzazione /asincrono/utilizzo misto.
Per ampliare ulteriormente, ecco un'implementazione del pool molto semplice, che può sicuramente essere ulteriormente migliorata:
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;
}
}