#c# #redis #stackexchange.redis
#c# #redis #stackexchange.redis
Вопрос:
Я пишу некоторый код на c # для записи на сервер redis. Код является многопоточным, поэтому всякий раз, когда я хочу внести изменения в определенную пару ключ: значение, мне нужно заблокировать «ключ»
Я использую StackExchange.Библиотека Redis. В этой библиотеке база данных идентификаторов интерфейса обозначает базу данных redis и предоставляет методы для чтения / записи в redis. Он имеет 2 метода, связанных с блокировкой: bool LockTake(ключ RedisKey, значение RedisValue, истечение срока действия, флаги CommandFlags = CommandFlags.None); amp; bool LockRelease (ключ RedisKey, значение RedisValue, флаги CommandFlags = CommandFlags.None);
Однако, согласно этому сообщению, LockTake() может блокировать только несуществующие ключи: https://github.com/StackExchange/StackExchange .Redis/проблемы /144
Но я хочу заблокировать ключ, даже если он был создан, поскольку несколько потоков могут попытаться обновить его одновременно. Как я могу это сделать на c #?
Комментарии:
1. Поместите свои изменения в блок блокировки (объекта) {}. Имейте в виду, что причина, по которой команда LockTake библиотеки Redis работает только с несуществующими ключами, заключается в том, что она позволяет избежать состояния гонки, когда поток A пытается установить значение для ключа «Z» равным 1, а поток B пытается установить значение для ключа «Z» равным 2. Если это должно было произойти, и кажется, что это то, для чего вы кодируете, вам нужно будет выяснить, какой поток должен «выиграть».
Ответ №1:
Вы можете использовать библиотеку блокировки на основе ключей, такую как та, которую я вызвал AsyncKeyedLock
. Он доступен на GitHub и упакован в NuGet.
Пример использования:
var locker = new AsyncKeyedLocker<string>(o =>
{
o.PoolSize = 20;
o.PoolInitialFill = 1;
});
// asynchronous code
using (await locker.LockAsync(key, cancellationToken))
{
...
}
// synchronous code
using (locker.Lock(key))
{
...
}