Jeg tror, du er ved at blive forvirret her. ConnectionMultiplexer
bliver ikke "blokeret". Oprettelse af en ConnectionMultiplexer
giver dig et fabrikslignende objekt, som du kan oprette IDatabase
med tilfælde. Du bruger derefter disse forekomster til at udføre normale Redis-forespørgsler. Du kan også lave Redis-forespørgsler med selve forbindelsesmultiplekseren, men det er serverforespørgsler og vil næppe blive gjort ofte.
Så for at gøre tingene korte, kan det hjælpe enormt at have en pulje af forbindelsesmultipleksere, uanset synkronisering /async/blandet brug.
For at udvide yderligere, er her en meget enkel poolimplementering, som bestemt kan forbedres yderligere:
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;
}
}