dotnet / dotnet/SqlClient

Managed SNI named pipe connections ignore command timeout

Open
#3,755 0 comments 1 reaction 0 assignees View on GitHub
ActiveIssue Area\Tests
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.