C# IMemoryCache在应用程序启动时不保存数据

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();

我创建了一个全新的ASP.NET核心Web API项目。下面是Startup.cs中的
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正在使用的服务提供商。我没有尝试过,但我猜它们将返回不同的实例。