Skip to content

Cancelling PrepareAsync() closes the connection #4209

@madelson

Description

@madelson

Steps to reproduce

This block of code reproduces the issue:

using var connection = new NpgsqlConnection(connectionString);
await connection.OpenAsync();
while (connection.State == ConnectionState.Open)
{
	using var command = connection.CreateCommand();
	command.CommandText = "SELECT 1";
	using var cts = new CancellationTokenSource();
	using var barrier = new Barrier(2); // helps with the timing
	var cancelTask = Task.Run(() => { barrier.SignalAndWait(); cts.Cancel(); });
	barrier.SignalAndWait();
	try {
		await command.PrepareAsync(cts.Token);
		//await command.ExecuteNonQueryAsync(cts.Token); // if we do this INSTEAD OF PrepareAsync, the loop does not exit
	}
	catch (OperationCanceledException) { }
	catch (Exception ex) { Console.WriteLine($"caught {ex.GetType()}"); } // we hit System.NullReferenceException
}

// in theory, we should never get here because we aren't closing the connection,
// but we actually get here quite quickly
Console.WriteLine(connection.State);

The issue

Cancelling an async operation should cause that operation to abort but should not affect the state of the connection. It should be fine to start one operation on a connection, abort it, and then start another one after the cancellation completes.

However, I am finding that cancelling the PrepareAsync() operation specifically causes the connection to become closed.

Here is the exception thrown by PrepareAsync when this happens:

System.NullReferenceException: Object reference not set to an instance of an object.
   at Npgsql.Internal.NpgsqlConnector.ReadMessage(Boolean async, DataRowLoadingMode dataRowLoadingMode, Boolean readingNotifications)
   at Npgsql.NpgsqlCommand.<Prepare>g__PrepareLong|88_1(NpgsqlCommand command, Boolean async, NpgsqlConnector connector, CancellationToken cancellationToken)
   at My code

Further technical details

Npgsql version: 6.0.1 and 5.0.4 (only tried those two versions)
PostgreSQL version: 12
Operating system: Windows 10

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions