Managed SNI named pipe connections ignore command timeout
- Dominant language
- C#
- Stars
- 989
- Forks
- 340
- Avg merge
- 4d 19h
- Merged PRs (30d)
- 72
Description
### Describe the bug
`SqlCommand.ExecuteReader` over a named pipe connection does not honor `CommandTimeout`. The `TimeoutCancelNamedPipe` manual test (src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlCommand/SqlCommandCancelTest.cs) expects a `SqlException`
when executing `WAITFOR DELAY '00:01:00'` with `CommandTimeout = 1`, but on .NET (Managed SNI) no exception is ever thrown. Instead, `ExecuteReader` blocks until the delay finishes and then returns rows. This regressed when the test was re-enabled for netcore CI and now fails consistently.
There is no exception to paste because the command completes successfully after ~60 seconds. The server output is the normal result set.
### To reproduce
```csharp
using Microsoft.Data.SqlClient;
using System;
var builder = new SqlConnectionStringBuilder(
Environment.GetEnvironmentVariable("MDSC_NP_CONN_STR")) // e.g. np:\\.\pipe\sql\query
{
PacketSize = 512
};
using SqlConnection connection = new SqlConnection(builder.ConnectionString);
using SqlCommand command = connection.CreateCommand();
command.CommandTimeout = 1;
command.CommandText = "WAITFOR DELAY '00:01:00'; SELECT 1";
connection.Open();
// Expected: SqlException (Execution Timeout Expired).
// Actual: blocks ~60s, returns result set without throwing.
using SqlDataReader reader = command.ExecuteReader();
### Expected behavior
ExecuteReader should honor CommandTimeout and throw SqlException/Execution Timeout Expired after ~1 second, matching the TCP transport and .NET Framework behavior.
### Further technical details
Microsoft.Data.SqlClient version: current main (managed SNI path)
.NET target: .NET 8.0 (net8.0-windows) – CI agent
SQL Server version: SQL Server 2019/2022 (default CI instance)
Operating system: Windows Server 2022 (Azure Pipelines)
### Additional context
In Managed SNI, SniNpHandle.Receive(out SniPacket packet, int timeout) ignores the timeout argument and simply calls _stream.Read. Because NamedPipeClientStream.ReadTimeout isn’t set and the method never observes the cancellation token, the read blocks indefinitely until the server responds. Consequently command timeouts and attention packets cannot break out of a wait, so timeout-based tests fail and user code can hang when relying on CommandTimeout. Request: honor the timeout parameter (e.g., set ReadTimeout, poll with WaitForPipeDrain, or use overlapped I/O that can be canceled) so named pipe connections behave consistently with TCP.
Contributor guide
Assessment
This issue has not been assessed yet.