From 9c668c88bfd0f6a68b12c5da5453467717f79376 Mon Sep 17 00:00:00 2001 From: Cory Rivera Date: Wed, 26 Apr 2017 21:40:16 -0700 Subject: [PATCH] Add Async flag to SqlClient NamedPipes' PipeStream to resolve an issue with connection hangs while using MARS over NP. (#19022) --- .../System/Data/SqlClient/SNI/SNINpHandle.cs | 6 +++++- .../SQL/LocalDBTest/LocalDBTest.cs | 19 +++++++++++++++++-- .../ManualTests/SQL/MARSTest/MARSTest.cs | 18 ++++++++++++++++++ 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNINpHandle.cs b/src/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNINpHandle.cs index 2dccfe288041..3f19377dbd28 100644 --- a/src/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNINpHandle.cs +++ b/src/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNINpHandle.cs @@ -46,7 +46,11 @@ public SNINpHandle(string serverName, string pipeName, long timerExpire, object try { - _pipeStream = new NamedPipeClientStream(serverName, pipeName, PipeDirection.InOut, PipeOptions.WriteThrough, Security.Principal.TokenImpersonationLevel.None); + _pipeStream = new NamedPipeClientStream( + serverName, + pipeName, + PipeDirection.InOut, + PipeOptions.Asynchronous | PipeOptions.WriteThrough); bool isInfiniteTimeOut = long.MaxValue == timerExpire; if (isInfiniteTimeOut) diff --git a/src/System.Data.SqlClient/tests/ManualTests/SQL/LocalDBTest/LocalDBTest.cs b/src/System.Data.SqlClient/tests/ManualTests/SQL/LocalDBTest/LocalDBTest.cs index c39e3dfbce1e..af055866de75 100644 --- a/src/System.Data.SqlClient/tests/ManualTests/SQL/LocalDBTest/LocalDBTest.cs +++ b/src/System.Data.SqlClient/tests/ManualTests/SQL/LocalDBTest/LocalDBTest.cs @@ -13,10 +13,25 @@ public static class LocalDBTest [ConditionalFact(nameof(IsLocalDBEnvironmentSet))] public static void LocalDBConnectionTest() { - SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder("server=(localdb)\\MSSQLLocalDB"); + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(@"server=(localdb)\MSSQLLocalDB"); builder.IntegratedSecurity = true; builder.ConnectTimeout = 2; - using (SqlConnection connection = new SqlConnection(builder.ConnectionString)) + OpenConnection(builder.ConnectionString); + } + + [ConditionalFact(nameof(IsLocalDBEnvironmentSet))] + public static void LocalDBMarsTest() + { + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(@"server=(localdb)\MSSQLLocalDB;"); + builder.IntegratedSecurity = true; + builder.MultipleActiveResultSets = true; + builder.ConnectTimeout = 2; + OpenConnection(builder.ConnectionString); + } + + private static void OpenConnection(string connString) + { + using (SqlConnection connection = new SqlConnection(connString)) { connection.Open(); using (SqlCommand command = new SqlCommand("SELECT @@SERVERNAME", connection)) diff --git a/src/System.Data.SqlClient/tests/ManualTests/SQL/MARSTest/MARSTest.cs b/src/System.Data.SqlClient/tests/ManualTests/SQL/MARSTest/MARSTest.cs index f8fc4e1f0060..0293bda56502 100644 --- a/src/System.Data.SqlClient/tests/ManualTests/SQL/MARSTest/MARSTest.cs +++ b/src/System.Data.SqlClient/tests/ManualTests/SQL/MARSTest/MARSTest.cs @@ -13,6 +13,24 @@ public static class MARSTest { private static readonly string _connStr = (new SqlConnectionStringBuilder(DataTestUtility.TcpConnStr) { MultipleActiveResultSets = true }).ConnectionString; + [CheckConnStrSetupFact] + public static void NamedPipesMARSTest() + { + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(DataTestUtility.NpConnStr); + builder.MultipleActiveResultSets = true; + builder.ConnectTimeout = 5; + + using (SqlConnection conn = new SqlConnection(builder.ConnectionString)) + { + conn.Open(); + using (SqlCommand command = new SqlCommand("SELECT @@SERVERNAME", conn)) + { + var result = command.ExecuteScalar(); + Assert.NotNull(result); + } + } + } + #if DEBUG [CheckConnStrSetupFact] public static void MARSAsyncTimeoutTest()