-
Notifications
You must be signed in to change notification settings - Fork 875
Milestone
Description
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
Reactions are currently unavailable