Closed gercobrandwijk closed 3 weeks ago
Hi @gercobrandwijk and thanks for using FusionCache!
In general when using eager refresh or soft/hard timeouts a factory can, as you observed, finish running after the original GetOrSet method call.
The main example is EF with ASP.NET, where the DbContext is usually scoped and automatically provided by the DI container.
The solution in this case is to use an IServiceScopeFactory
and be explicit about the lifetime, disposing it manually inside the factory (normally with a using
statement).
Hope this helps.
ps: one question, if I may: why are you not on v1.0+? Just out of curiosity.
Check this issue also https://github.com/ZiggyCreatures/FusionCache/issues/119#issuecomment-2173530857
I also opened an issue in the EF repo for potential alternative solutions, see here.
The solution in this case is to use an
IServiceScopeFactory
and be explicit about the lifetime, disposing it manually inside the factory (normally with ausing
statement).
Thanks, makes a lot of sense obviously. Tried it out, and it works fine :)
Check this issue also #119 (comment)
Sorry that I missed that one, I even searched for it in the issue list, but was not able to find it for some reason.
I also opened an issue in the EF repo for potential alternative solutions, see here.
The possible solution that you are suggesting there is I think not working in all scenarios. Imagine a factory that look like this:
async () => { await Task.Delay(5000); return await myService.GetAllItems(); }
In this scenario, when the DbContext/Service wants to be disposed, no query is actually running yet (because it still has to start), so it will still dispose and then after 5 sec give the same Disposed exception. Therefor just managing the scope by yourself would simply be the best I think.
ps: one question, if I may: why are you not on v1.0+? Just out of curiosity.
We still have to update, no particular reason ;)
Thanks, makes a lot of sense obviously. Tried it out, and it works fine :)
Cool, happy it helped!
The possible solution that you are suggesting there is I think not working in all scenarios. Imagine a factory that look like this:
async () => { await Task.Delay(5000); return await myService.GetAllItems(); }
In this scenario, when the DbContext/Service wants to be disposed, no query is actually running yet (because it still has to start), so it will still dispose and then after 5 sec give the same Disposed exception. Therefor just managing the scope by yourself would simply be the best I think.
Although this specific example is kinda exotic, I get your point and it makes sense: I would say the general rationale is that a deferred (automatic) dispose would still not handle queries that are not started yet when the scope ends. Probably a manual scope management is the best solution.
We still have to update, no particular reason ;)
Got it 🙂
Describe the question
After enabling Eager Refresh I started seeing ObjectDisposedException, because the services that are used in the factory are being disposed while the factory is still runinng, but the request that trigger the Eager Refresh already finished.
To Reproduce
Question
What would be the advised way to handle scenario's like this?
Versions
I've encountered this issue on: