dotnet / dotnet/efcore

Deferred Dispose (maybe?)

Open
#33,892 7 comments 2 reactions 0 assignees View on GitHub
area-dbcontext customer-reported needs-design
Dominant language
C#
Stars
14.8k
Forks
3.4k
PR merge metrics
PR metrics pending

Description

## The Problem

When using EF Core with ASP.NET the typical way is to get a `DbContext` via DI, and this means inherently with a scoped lifetime: this, in turn, means that when the HTTP request finishes, the scope will be disposed.

Normally this is all good, but sometimes we need to let a query run after the HTTP request finishes.

An example of this scenario in which I run into (actually, some of my community members did) is when using EF with [FusionCache](https://github.com/ZiggyCreatures/FusionCache) with [Soft/Hard Timeouts](https://github.com/ZiggyCreatures/FusionCache/blob/main/docs/Timeouts.md) enabled: this feature allows for a slow query that is taking too much time to be finished in the background, while temporarily returning the stale value, to allow for faster response times without missing on a cache update.

A different but similar feature that has a similar behavior is [Eager Refresh](https://github.com/ZiggyCreatures/FusionCache/blob/main/docs/EagerRefresh.md).

For example here's [an issue](https://github.com/ZiggyCreatures/FusionCache/issues/21) opened for this.

## The Current Solution (Workaround?)

The solution highlighted in the original consist in changing the way to use EF, from a scoped `DbContext` automatically injected via DI to using `IServiceScopeFactory` and manually create scopes.

It did work, and seemingly well, but it doesn't look spectacular so I'm looking for potential alternatives.

## A Possible Solution

Something different I've been thinking about is the concept of deferred scopes: by enabling such a feature it would be possible to defer the actual disposal of a `DbContext`, so that when calling `Dispose()` (either manually or automatically by ASP.NET's DI scope handling) the underlying disposal logic will be executed ONLY if there is no query being executed.

If instead there's a query still running, the disposal will be executed as soon as the query will complete, either successfully or by failing/throwing.

I'm not sure this is the way to go, maybe it's a stupid idea and there may be potential consequences for acting in this way, but this is the reason I'm opening this issue: to talk about such possibility and see if something comes up.

Thanks in advance for your time!

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.