ASP.NET 5迁移后IMemoryCache抛出System.ObjectDisposedException异常问题求助
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 inConfigureServices(before registering services that depend on it). - Add debug logging to check the
HashCodeof_memoryCacheinMyClass—it should be the same across all instances if it’s a singleton. - Verify no third-party libraries are overriding the
IMemoryCacheregistration (some caching libraries replace the default implementation).
内容的提问来源于stack exchange,提问作者Wouter Vandenputte

