DI034

HttpContext Used in Fire-and-Forget Background Work

An HttpContext value — a parameter, local, or field of that type — or a read of IHttpContextAccessor.HttpContext, inside background work started with Task.Run or TaskFactory.StartNew whose task is thrown away or observed only through a finite/cancelable Wait(...) Boolean result.

Warning Default severity · Code fix: No

Why it matters

ASP.NET Core pools HttpContext and resets it as soon as the response has been written, and the accessor's backing AsyncLocal is cleared or reassigned to the next request. Work that outlives the request therefore reads a context whose request, response, features, and RequestServices have already been torn down. The usual symptom is a NullReferenceException or ObjectDisposedException under load, and the worst one is reading another user's request data from a recycled context.

README problem example

public void Handle(HttpContext context)
{
    _ = Task.Run(() => _audit.Write(context.TraceIdentifier));  // DI034
}

README better pattern

public void Handle(HttpContext context)
{
    var traceId = context.TraceIdentifier;
    _ = Task.Run(() => _audit.Write(traceId));
}

No — which values to hoist out of the context is a decision about what the background work actually needs.

Guardrails

When DI034 stays silent

A task that is awaited, returned, stored in a local, or waited on to guaranteed completion keeps the request alive until the work completes and stays silent. A framework Task.Wait with a finite timeout or cancelable token can return while work continues, so storing or returning its Boolean result still reports; user-defined extension methods named Wait stay conservative and silent. Background work that touches no context also stays silent. Reading the accessor *inside* the work is reported too, since by then the AsyncLocal has already moved on.

Repo sample extraction

Examples pulled from the sample app

Open full sample file

Sample app off-request HttpContext warning

    public sealed class Bad_AuditFromBackgroundWork
    {
        public void Handle(HttpContext context)
        {
            // DI034: the response completes and the context is recycled while this still runs.
            _ = Task.Run(() => Console.WriteLine(context.GetHashCode()));
        }
    }

Sample app copy-values-first pattern

    public sealed class Good_CopyValuesBeforeBackgroundWork
    {
        public void Handle(HttpContext context)
        {
            var traceId = context.GetHashCode();
            _ = Task.Run(() => Console.WriteLine(traceId));
        }
    }

Related guides

  • No problem-guide pages point here yet.

Nearby diagnostics

Other rules in this family

All 37 rules