Jag tror att du börjar bli förvirrad här. ConnectionMultiplexer
"blir inte blockerad". Skapa en ConnectionMultiplexer
ger dig ett fabriksliknande objekt med vilket du kan skapa IDatabase
instanser. Du använder sedan dessa instanser för att utföra normala Redis-frågor. Du kan också göra Redis-frågor med själva anslutningsmultiplexern, men det är serverfrågor och kommer sannolikt inte att göras ofta.
Så, för att göra saker kort, kan det hjälpa oerhört att ha en pool av anslutningsmultiplexer, oavsett synkronisering /async/blandad användning.
För att expandera ytterligare, här är en mycket enkel poolimplementering, som säkert kan förbättras ytterligare:
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;
}
}