我有一个ASP.NET核心应用程序,并且尝试使用Redis缓存-但是我收到一条错误消息,说无法访问已处置的对象,因此我必须未正确设置我的缓存类。我已经将Cache服务类放入我自己的Nuget存储库中,以便其他应用程序可以将它与其他应用程序中的appsettings.json传递不同的Db号码
我正在使用内置的.NET Core DI来注册缓存服务,如下所示:
services.AddTransient<ICacheService, CacheService>();
然后按如下方式在我的应用程序中使用缓存服务:
var dataFromCache = _cacheService.TryGetCachedObject<List<MyObject>>(cacheKey);
在nuget pacakge中我的Cache服务的实现如下:
public class CacheService : ICacheService, IDisposable
{
public virtual T TryGetCachedObject<T>(string cacheKey)
{
if (RedisCacheHandler.Cache.KeyExists(cacheKey))
{
return JsonConvert.DeserializeObject<T>(RedisCacheHandler.Cache.StringGet(cacheKey));
}
return default(T);
}
//other metjhods omitted for brevity
我在行if (RedisCacheHandler.Cache.KeyExists(cacheKey))
上获得了无法访问的已处置对象异常
我的redis缓存处理程序类在下面(如果我尝试不成功的话,注释掉的行。
public static class RedisCacheHandler
{
private static Lazy<ConnectionMultiplexer> _lazyConnection;
private static ConnectionMultiplexer Connection => _lazyConnection.Value;
//private static CacheSettings _cacheSettings;
public static IDatabase Cache { get; set; }
//public static IDatabase Cache => Connection.GetDatabase(Convert.ToInt32(_cacheSettings.DbNumber));
//private static readonly Lazy<ConnectionMultiplexer> LazyConnection
// = new Lazy<ConnectionMultiplexer>(() => ConnectionMultiplexer.Connect(_cacheSettings.Connection));
//public static ConnectionMultiplexer Connection => LazyConnection.Value;
public static void AddRedisCacheHandler(this IServiceCollection services, IConfiguration configuration)
{
var cacheSettings = new CacheSettings();
configuration.Bind("CacheSettings", cacheSettings);
//_cacheSettings = cacheSettings;
_lazyConnection = new Lazy<ConnectionMultiplexer>(() => ConnectionMultiplexer.Connect(cacheSettings.Connection));
Cache = Connection.GetDatabase(Convert.ToInt32(cacheSettings.DbNumber));
}
}
然后我在ConfigureServices
方法中的asp.net核心启动类中调用AddRedisCacheHandler方法,如下所示:
services.AddRedisCacheHandler(Configuration);
编辑
它的用法是我点击了一个API控制器来获取参考数据。 API控制器调用服务层,然后服务层将检查数据是否在缓存中,然后从那里进行检索,将从数据库中获取数据并将其在缓存中设置24小时
private readonly IMyService _myService
public MyController(IMyService myService)
{
_myService = myService;
}
[Route("SomeReferenceData")]
public IEnumerable<SomeDto> GetReferenceData()
{
var data = _myService.GetRefData();
//do stuff and return
}
在服务层,代码为:
public class MyService : IMyService
{
private readonly ICacheService _cacheService;
private readonly CacheSettings _cacheSettings;
public MyService(CacheSettings cacheSettings, ICacheService cacheService)
{
_cacheSettings = cacheSettings;
_cacheService = cacheService;
}
public virtual IEnumerable<MyObject> GetRefData()
{
string cacheKey = CachingConstants.CacheKey;
var data = _cacheService.TryGetCachedObject<List<MyObject>>(cacheKey);
if (data != null)
{
return data;
}
//go get data from db
_cacheService.SetCachedObject<IEnumerable<MyObject>>(cacheKey, countries, Convert.ToInt32(_cacheSettings.DurationLongMinutes));
return data;
}
从启动开始,我正在调用以下命令来注册包括缓存服务在内的所有依赖项:
services.RegisterServiceDependencies();
public static class ServiceConfig
{
public static void RegisterServiceDependencies(this IServiceCollection services)
{
services.AddTransient<ICacheService, CacheService>();
//lots of other services
答案 0 :(得分:1)
您在这里自杀。从字面上看,这没有必要。 ASP.NET Core具有对分布式缓存的内置支持,包括使用Redis作为提供程序。在您的import tkinter as tk
from tkinter import ttk
root=tk.Tk()
root.geometry("+50+50")
var=tk.IntVar()
var.set(0)
current_state=tk.StringVar()
text=[' Checkbutton: Off ', ' Checkbutton: On ', ' CB to Third State ']
def label_update():
current_state.set(text[var.get()])
cb=ttk.Checkbutton(root, variable=var, text='Test Box', command=label_update)
cb.grid()
seq=[1,2]
def tick():
""" Sets var (tk.IntVar) to 0, 1, 2 in sequence for each tick """
try:
var.set(seq[var.get()])
if var.get()>1: cb.state(['alternate']) # alternate on
except IndexError:
cb.state(['!alternate']) # alternate off
var.set(0) # reset count
label_update()
ttk.Button(root, text=" Click to cycle through states ", command=tick).grid()
ttk.Label(root, textvariable=current_state).grid()
label_update()
root.title("Checkbutton Issue")
root.mainloop()
中,只需执行以下操作:
Startup.cs
然后,当您需要利用缓存时,只需注入services.AddDistributedRedisCache(options =>
{
options.Configuration = "localhost";
options.InstanceName = "SampleInstance";
});
。如果您想要一种独立的方法来自动序列化/反序列化缓存中的值,则可以简单地添加一些扩展方法:
IDistributedCache
如果您坚持为此使用单独的public static class IDistributedCacheExtensions
{
public static async Task<T> GetAsync<T>(this IDistributedCache cache, string key) =>
JsonConvert.DeserializeObject<T>(await cache.GetStringAsync(key));
public static Task Set<T>(this IDistributedCache cache, string key, T value) =>
cache.SetStringAsync(key, JsonConvert.SerializeObject(value));
}
类,则只需将CacheService
注入其中,然后在其中进行工作即可。