You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET 5迁移后IMemoryCache抛出System.ObjectDisposedException异常问题求助

Fixing "Cannot access a disposed object" for IMemoryCache in ASP.NET 5

I’ve run into this exact issue when migrating projects from ASP.NET Framework 4.7.2 to ASP.NET 5, even with services.AddMemoryCache() properly configured. Let’s break down the most likely causes and actionable fixes:

1. Double-check your MemoryCache registration

First, confirm you haven’t accidentally overridden the default singleton lifecycle of IMemoryCache. The correct setup in Startup.cs (or Program.cs for .NET 6+ top-level statements) is straightforward:

services.AddMemoryCache();

Avoid manually creating MemoryCache instances and registering them with shorter lifetimes (like Scoped), which will get disposed when the request scope ends:

// ❌ Bad: Manually registering a scoped MemoryCache leads to premature disposal
services.AddScoped<IMemoryCache>(sp => new MemoryCache(new MemoryCacheOptions()));

AddMemoryCache() registers IMemoryCache as a singleton by default—this is exactly what you need for a shared application cache.

2. Fix async context mismatches

If you’re accessing the cache in an async callback (like with ContinueWith) or a background thread that outlives the original request, you might hit context-related disposal issues. Always use await instead of ContinueWith to maintain proper context:

// ❌ Risky: ContinueWith detaches from the original request context
someAsyncTask.ContinueWith(t => {
    _memoryCache.TryGetValue(_cacheKey, out object item);
});

// ✅ Safe: Await preserves the correct context
await someAsyncTask;
_memoryCache.TryGetValue(_cacheKey, out object item);

For background work, use ASP.NET’s built-in IHostedService or BackgroundService instead of raw threads—these handle service lifetimes properly.

3. Check custom cache wrappers for accidental disposal

If you have a custom cache wrapper class, make sure it’s not calling Dispose() on the injected IMemoryCache. Since the cache is a singleton, you never want to dispose it manually—let the DI container manage its lifecycle:

// ❌ Bad: Wrapper disposes the singleton cache (breaks everything!)
public class CustomCache : IDisposable
{
    private readonly IMemoryCache _innerCache;

    public CustomCache(IMemoryCache innerCache) => _innerCache = innerCache;

    public void Dispose()
    {
        _innerCache.Dispose(); // This kills the shared cache for all components
    }
}

Remove any calls to _memoryCache.Dispose() in custom code—they’re unnecessary and dangerous here.

4. Validate MyClass service registration

Ensure MyClass is registered with the DI container correctly, not manually instantiated (which bypasses proper lifetime management):

// ✅ Good: Let DI handle dependency injection
services.AddScoped<MyClass>(); // Use Transient/Singleton based on your needs

// ❌ Bad: Manual instantiation can create invalid cache instances
services.AddScoped<MyClass>(sp => new MyClass(new MemoryCache(new MemoryCacheOptions())));

Quick validation steps

  • Confirm services.AddMemoryCache() is called early in ConfigureServices (before registering services that depend on it).
  • Add debug logging to check the HashCode of _memoryCache in MyClass—it should be the same across all instances if it’s a singleton.
  • Verify no third-party libraries are overriding the IMemoryCache registration (some caching libraries replace the default implementation).

内容的提问来源于stack exchange,提问作者Wouter Vandenputte

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 03:17:47