4

I am getting this message:

System.ObjectDisposedException: Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.

Controller:

    [HttpGet]
    public IActionResult GetAllTags()
    {
        try
        {
            return Ok(GetAll());
        }
        catch(Exception ex)
        {
            return ControllerHelper.LogAndReturnBadRequest(_logger, ex);
        }
    }

    private IEnumerable<TagDto> GetAll()
    {
            IEnumerable<TagDto> tags;
            if (!_cache.TryGetValue(CacheKeys.States, out tags))
            {
                tags = _service.GetAll()?.Select(t => _mapper.Map<TagDto>(t));

                if(tags != null)
                    _cache.Set(CacheKeys.States, tags);
            }

            return tags;
    }

Startup.cs

services.AddMemoryCache();

I was debugging the code line by line, but even after the last line of my code, there is no error at all.

The error I saw was in Kestrel console. Worth to notice, the error only happen when fetching tags from the _cache, not happen on the first time when tags fetched directly from database.

enter image description here

Here is what I got from Postman request:

enter image description here

Many similar questions referring to dispose objects, but here you can see that I do not have dispose(), or using() in my code.

halfer
  • 19,824
  • 17
  • 99
  • 186
Franva
  • 6,565
  • 23
  • 79
  • 144
  • What line are you getting this error on? – Ron Beyer May 02 '19 at 00:52
  • @RonBeyer I was debugging it line by line, but even after return Ok(GetAll()); there is no exception happen. I will update my post to include the response in Postman and error in Kestrel console. – Franva May 02 '19 at 00:57
  • @RonBeyer I updated the error from Kestrel console and attached the postman response – Franva May 02 '19 at 01:07
  • Seems like your DbContext is disposed. – Kirill Polishchuk May 02 '19 at 01:10
  • hi @KirillPolishchuk but I stored the tags in my cache already, so even DbContext is disposed, it shouldn't affect my cache, isn't it? – Franva May 02 '19 at 01:46
  • @Franva - were you able to solve this issue? I am getting hit with the exact same problem. I tried the ToList() and still no luck. My Db context dependency is transient and is injected in service layer as scoped. I noticed that shifting to a singleton instance removes this error; but that is not what I want – Saket Jun 18 '20 at 18:25
  • 1
    Works - My resultset from database had multiple 'IEnumerable' properties - I had to invoke ToList on each for explicit evaluation. – Saket Jun 18 '20 at 20:46
  • Just FYI, closely related link: https://stackoverflow.com/questions/53047209/why-is-dbcontext-is-disposed-after-putting-it-in-imemorycache-net-core-ef-co – crazyTech Jun 21 '22 at 11:44

1 Answers1

1

My guess is you need to hydrate the results of your query before storing in in the cache. Linq uses deferred execution, which means that the underlying source won't actually be queried until you try to enumerate the results. So you are just storing a query in the cache, and by the time you try to retrieve the actual data, the underlying context is disposed.

Add a ToList to your query and store the list in the cache:

tags = _service.GetAll()?.Select(t => _mapper.Map<TagDto>(t)).ToList();

I would also note that the result of a linq query that returns a sequence will never be null. It might be empty, so if you don't want to cache an empty result you could change your null check to if (tags.Any()).

D Stanley
  • 149,601
  • 11
  • 178
  • 240
  • Just FYI, closely related link: https://stackoverflow.com/questions/53047209/why-is-dbcontext-is-disposed-after-putting-it-in-imemorycache-net-core-ef-co – crazyTech Jun 21 '22 at 11:44