Я использую следующий одноэлементный класс для получения/установки/удаления значений из кэша Azure Redis для одной из моих личных разработок.
using StackExchange.Redis;
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace PoC
{
public sealed class CacheManager
{
public static object mutex = new object();
public static string EndPoint { get; set; }
public static string Password { get; set; }
public static bool UseSsl { get; set; }
public static int ConnectRetry { get; set; }
public static int KeepAlive { get; set; }
public static int ConnectTimeout { get; set; }
private static ConfigurationOptions ConfigurationOptions;
private static readonly CacheManager instance = new CacheManager();
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static CacheManager() { }
private CacheManager()
{
ConfigurationOptions = new ConfigurationOptions
{
Password = Password,
Ssl = UseSsl,
AbortOnConnectFail = false,
ConnectRetry = ConnectRetry,
KeepAlive = KeepAlive,
ConnectTimeout = ConnectTimeout
};
}
public static CacheManager Instance { get { return instance; } }
public static string ConnectionString { get; set; }
Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() =>
{
return ConnectionMultiplexer.Connect(ConfigurationOptions);
});
IDatabase Database => lazyConnection.Value.GetDatabase();
public void Set<T>(string key, T value)
{
lock (mutex)
{
Database.StringSet(key, ToByteArray(value));
}
}
public T Get<T>(string key)
{
T result = FromByteArray<T>(Database.StringGet(key));
return result;
}
public bool Remove(string key)
{
lock (mutex)
{
var removed = Database.KeyDelete(key);
return removed;
}
}
public byte[] ToByteArray<T>(T obj)
{
if (obj == null)
return null;
BinaryFormatter bf = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream())
{
bf.Serialize(ms, obj);
return ms.ToArray();
}
}
public T FromByteArray<T>(byte[] data)
{
if (data == null)
return default(T);
BinaryFormatter bf = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream(data))
{
object obj = bf.Deserialize(ms);
return (T)obj;
}
}
}
}
Здесь я использовал блокировку при вставке значений в базу данных или удалении значений из базы данных. Но из следующего поста я узнал, что Redis — это однопоточная база данных, и все операции атомарны.
Есть ли какой-либо механизм блокировки в Кэш Azure Redis при обновлении элемента?
Поэтому я считаю, что блокировка, которую я использовал, не нужна и может привести к некоторым проблемам с производительностью. Пожалуйста, поправьте меня, если я ошибаюсь. Я устанавливаю переменные (EndPoint, Password и т. д.) один раз в событии Application_Start
. Был бы признателен за помощь.