C# IMemoryCache在应用程序启动时不保存数据
我创建了一个全新的ASP.NET核心Web API项目。下面是Startup.cs中的C# IMemoryCache在应用程序启动时不保存数据,c#,asp.net-core,.net-core,C#,Asp.net Core,.net Core,我创建了一个全新的ASP.NET核心Web API项目。下面是Startup.cs中的ConfigureServices: public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); services.AddMemoryCache();
ConfigureServices
:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddMemoryCache();
var serviceProvider = services.BuildServiceProvider();
var cache = serviceProvider.GetService<IMemoryCache>();
cache.Set("key1", "value1");
//_cahce.Count is 1
}
public void配置服务(IServiceCollection服务)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddMemoryCache();
var serviceProvider=services.BuildServiceProvider();
var cache=serviceProvider.GetService();
cache.Set(“key1”、“value1”);
//_计数是1
}
如您所见,我向IMemoryCache添加了一项。这是我的控制器:
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
private readonly IMemoryCache _cache;
public ValuesController(IMemoryCache cache)
{
_cache = cache;
}
[HttpGet("{key}")]
public ActionResult<string> Get(string key)
{
//_cahce.Count is 0
if(!_cache.TryGetValue(key, out var value))
{
return NotFound($"The value with the {key} is not found");
}
return value + "";
}
}
[路由(“api/[控制器]”)]
[ApiController]
公共类值控制器:控制器库
{
专用只读IMemoryCache\u缓存;
公共价值控制器(IMemoryCache缓存)
{
_缓存=缓存;
}
[HttpGet(“{key}”)]
公共操作结果获取(字符串键)
{
//_计数为0
if(!\u cache.TryGetValue(键,输出变量值))
{
return NotFound($“找不到带{key}的值”);
}
返回值+“”;
}
}
当我请求
https://localhost:5001/api/values/key1
,缓存为空,我收到未找到响应 正如@selloape所说,如果您手动调用BuildServicesProvider,则您正在创建一个新的提供者,该提供者将不会在您的控制器中使用
您可以使用托管服务初始化缓存
public class InitializeCacheService : IHostedService
{
private readonly IServiceProvider _serviceProvider;
public InitializeCacheService (IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public Task StartAsync(CancellationToken cancellationToken)
{
using (var scope = _serviceProvider.CreateScope())
{
var cache = _serviceProvider.GetService<IMemoryCache>();
cache.Set("key1", "value1");
}
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
}
公共类InitializeCacheService:iHosteService
{
私有只读服务器ViceProvider\u服务提供商;
公共InitializeCacheService(IServiceProvider服务提供商)
{
_服务提供者=服务提供者;
}
公共任务StartSync(CancellationToken CancellationToken)
{
使用(var scope=\u serviceProvider.CreateScope())
{
var cache=_serviceProvider.GetService();
cache.Set(“key1”、“value1”);
}
返回Task.CompletedTask;
}
公共任务StopAsync(CancellationToken CancellationToken)
{
返回Task.CompletedTask;
}
}
将其添加到ConfigureServices中
services.AddHostedService<InitializeCacheService>();
services.AddHostedService();
正如@selloape所说,如果您手动调用BuildServicesProvider,则您正在创建一个新的提供者,该提供者将不会在您的控制器中使用 您可以使用托管服务初始化缓存
public class InitializeCacheService : IHostedService
{
private readonly IServiceProvider _serviceProvider;
public InitializeCacheService (IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public Task StartAsync(CancellationToken cancellationToken)
{
using (var scope = _serviceProvider.CreateScope())
{
var cache = _serviceProvider.GetService<IMemoryCache>();
cache.Set("key1", "value1");
}
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
}
公共类InitializeCacheService:iHosteService
{
私有只读服务器ViceProvider\u服务提供商;
公共InitializeCacheService(IServiceProvider服务提供商)
{
_服务提供者=服务提供者;
}
公共任务StartSync(CancellationToken CancellationToken)
{
使用(var scope=\u serviceProvider.CreateScope())
{
var cache=_serviceProvider.GetService();
cache.Set(“key1”、“value1”);
}
返回Task.CompletedTask;
}
公共任务StopAsync(CancellationToken CancellationToken)
{
返回Task.CompletedTask;
}
}
将其添加到ConfigureServices中
services.AddHostedService<InitializeCacheService>();
services.AddHostedService();
简而言之,您在其中设置值的缓存实例与稍后检索的缓存实例不同。您不能在构建web主机时执行类似操作(即在
ConfigureServices
/Configure
中)。如果需要在启动时执行某些操作,则需要在构建web主机后在程序.cs
中执行:
public class Program
{
public static void Main(string[] args)
{
var host = CreateWebHostBuilder(args).Build();
var cache = host.Services.GetRequiredService<IMemoryCache>();
cache.Set("key1", "value1");
host.Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
}
公共类程序
{
公共静态void Main(字符串[]args)
{
var host=CreateWebHostBuilder(args.Build();
var cache=host.Services.GetRequiredService();
cache.Set(“key1”、“value1”);
host.Run();
}
公共静态IWebHostBuilder CreateWebHostBuilder(字符串[]args)=>
WebHost.CreateDefaultBuilder(args)
}
简而言之,您在其中设置值的缓存实例与稍后检索的缓存实例不同。您不能在构建web主机时执行类似操作(即,在ConfigureServices
/Configure
中。如果需要在启动时执行某些操作,则需要在构建web主机后在程序中执行。cs
:
public class Program
{
public static void Main(string[] args)
{
var host = CreateWebHostBuilder(args).Build();
var cache = host.Services.GetRequiredService<IMemoryCache>();
cache.Set("key1", "value1");
host.Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
}
公共类程序
{
公共静态void Main(字符串[]args)
{
var host=CreateWebHostBuilder(args.Build();
var cache=host.Services.GetRequiredService();
cache.Set(“key1”、“value1”);
host.Run();
}
公共静态IWebHostBuilder CreateWebHostBuilder(字符串[]args)=>
WebHost.CreateDefaultBuilder(args)
}
你可以共享你的MemoryCache类吗?。为什么不使用Redis..这样在重新启动时它就不会丢失数据?你确定键的值与“key1”
的值相同吗?@federicoscamuzzi-我怀疑他们使用的是几乎不会成为“他们的”的。我怀疑您现在可能有两个服务提供商,因为您正在构建自己的服务提供商以添加到缓存中,但这可能不是ASP.NET正在使用的服务提供商。我没有尝试过,但我猜它们会返回不同的实例。您能共享MemoryCache类吗?。为什么不使用Redis..这样在重新启动时不会丢失数据?您确定吗key
的值与“key1”
?@federicoscamuzzi的值相同-我怀疑他们使用的是很难成为“他们的”。我怀疑您现在可能有2个服务提供商,因为您正在构建自己的服务提供商以添加到缓存中,但这可能不是ASP.NET正在使用的服务提供商。我没有尝试过,但我猜它们将返回不同的实例。