Visitar URL original
Disposing a ReplicationConnection while MoveNextAsync is pending: the call never completes, and Debug builds crash · Issue #6701 · npgsql/npgsql · GitHub
Skip to content

Disposing a ReplicationConnection while MoveNextAsync is pending: the call never completes, and Debug builds crash #6701

Description

@Brar

ReplicationConnection.DisposeAsync cancels the stream and then calls MoveNextAsync on the stream's enumerator itself (ReplicationConnection.cs:252-271). If the consumer's MoveNextAsync is still waiting for the next message, e.g. when a hosted service disposes the connection at shutdown while its loop awaits the next message, that second call re-enters the async iterator at the pending read and calls GetResult on its incomplete pooled ValueTask; that throws InvalidOperationException, which DisposeAsync swallows, and returns the read's state machine box to the pool. The consumer's call never completes. When the read finishes, its continuation runs on a recycled state machine box, which in Debug builds throws NullReferenceException on an I/O thread and kills the process.

With a mock walsender on main's source, Debug crashed in 3 of 3 runs, and in Release the call was still pending after 5 s in 3 of 3. On PostgreSQL 18.6, with the walsender's main thread suspended so that it can't answer the cancel first, the result was the same. When the server answers the cancel quickly, the race is usually won: 10 of 10 unforced live runs didn't crash. DisposeAsync's comment calls concurrent use a contract violation (:257-259), but a hang or a crash is a harsh result for a common shutdown pattern.

The same code is on the 8.0, 9.0 and 10.0 hotfix branches.

Activity

  1. added this to the 11.0.0 milestone on Oct 25, 2026
  2. self-assigned this
    on Oct 25, 2026
  3. added theissue type on Oct 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions