@@ -76,7 +76,7 @@ private static bool DoomMicrosoftDataConnection(SqlConnection connection)
7676 {
7777 if ( _internalConnectionField ? . GetValue ( connection ) is object internalConnection )
7878 {
79- var doomMethod = internalConnection . GetType ( ) . GetMethod ( "DoomThisConnection" , BindingFlags . NonPublic | BindingFlags . Instance ) ;
79+ MethodInfo doomMethod = internalConnection . GetType ( ) . GetMethod ( "DoomThisConnection" , BindingFlags . NonPublic | BindingFlags . Instance ) ;
8080 if ( doomMethod != null )
8181 {
8282 doomMethod . Invoke ( internalConnection , null ) ;
@@ -163,36 +163,41 @@ private void RunStressTest(
163163 var barrier = new Barrier ( ConcurrentConnections ) ;
164164 var countdown = new CountdownEvent ( ConcurrentConnections ) ;
165165
166- var command = string . IsNullOrWhiteSpace ( WaitForDelay )
167- ? "SELECT GETDATE()"
168- : $ "WAITFOR DELAY '{ WaitForDelay } '; SELECT GETDATE()";
169-
170- // Create regular threads (don't doom connections)
171- for ( int i = 0 ; i < ConcurrentConnections - 1 ; i ++ )
166+ try
172167 {
173- threads [ i ] = CreateWorkerThread (
174- connectionString , command , barrier , countdown , doomConnections : false , async ) ;
175- }
168+ var command = string . IsNullOrWhiteSpace ( WaitForDelay )
169+ ? "SELECT GETDATE()"
170+ : $ "WAITFOR DELAY ' { WaitForDelay } '; SELECT GETDATE()" ;
176171
177- // Create special thread that dooms connections (if we have multiple threads )
178- if ( ConcurrentConnections > 1 )
179- {
180- threads [ ConcurrentConnections - 1 ] = CreateWorkerThread (
181- connectionString , command , barrier , countdown , doomConnections : true , async, doomAction ) ;
182- }
172+ // Create regular threads (don't doom connections )
173+ for ( int i = 0 ; i < ConcurrentConnections - 1 ; i ++ )
174+ {
175+ threads [ i ] = CreateWorkerThread (
176+ connectionString , command , barrier , countdown , doomConnections : false , async) ;
177+ }
183178
184- // Start all threads
185- foreach ( var thread in threads . Where ( t => t != null ) )
186- {
187- thread . Start ( ) ;
188- }
179+ // Create special thread that dooms connections (if we have multiple threads)
180+ if ( ConcurrentConnections > 1 )
181+ {
182+ threads [ ConcurrentConnections - 1 ] = CreateWorkerThread (
183+ connectionString , command , barrier , countdown , doomConnections : true , async, doomAction ) ;
184+ }
189185
190- // Wait for completion
191- countdown . Wait ( ) ;
186+ // Start all threads
187+ foreach ( Thread thread in threads . Where ( t => t != null ) )
188+ {
189+ thread . Start ( ) ;
190+ }
192191
193- // Clean up synchronization objects
194- barrier ? . Dispose ( ) ;
195- countdown ? . Dispose ( ) ;
192+ // Wait for completion
193+ countdown . Wait ( ) ;
194+ }
195+ finally
196+ {
197+ // Clean up synchronization objects
198+ barrier ? . Dispose ( ) ;
199+ countdown ? . Dispose ( ) ;
200+ }
196201 }
197202
198203 /// <summary>
@@ -218,29 +223,27 @@ private Thread CreateWorkerThread(
218223 if ( doomConnections && doomAction != null )
219224 {
220225 // Dooming thread - barriers inside using block to doom before disposal
221- using ( var conn = new SqlConnection ( connectionString ) )
226+ using var conn = new SqlConnection ( connectionString ) ;
227+ if ( async)
222228 {
223- if ( async)
224- {
225- await conn . OpenAsync ( ) ;
226- }
227- else
228- conn . Open ( ) ;
229-
230- await ExecuteCommand ( command , async , conn ) ;
229+ await conn . OpenAsync ( ) ;
230+ }
231+ else
232+ conn . Open ( ) ;
231233
232- // Synchronize after command execution, before dooming
233- barrier . SignalAndWait( ) ;
234+ await ExecuteCommand ( command , async , conn ) ;
234235
235- // Doom connection before it gets disposed/returned to pool
236- if ( ! doomAction ( conn ) )
237- {
238- // fail test here.
239- }
236+ // Synchronize after command execution, before dooming
237+ barrier . SignalAndWait( ) ;
240238
241- // Synchronize after dooming - ensures all threads see the effect
242- barrier . SignalAndWait( ) ;
239+ // Doom connection before it gets disposed/returned to pool
240+ if ( ! doomAction ( conn ) )
241+ {
242+ throw new Exception ( "Unable to doom connection ") ;
243243 }
244+
245+ // Synchronize after dooming - ensures all threads see the effect
246+ barrier. SignalAndWait( ) ;
244247 }
245248 else
246249 {
@@ -266,10 +269,6 @@ private Thread CreateWorkerThread(
266269 }
267270 }
268271 }
269- catch ( Exception ex )
270- {
271- Console . WriteLine( $"Thread execution failed: {ex.Message}" ) ;
272- }
273272 finally
274273 {
275274 countdown . Signal ( ) ;
@@ -287,15 +286,13 @@ private static async Task ExecuteCommand(string command, bool async, SqlConnecti
287286 {
288287 try
289288 {
290- using ( var cmd = new SqlCommand ( command , conn ) )
289+ using var cmd = new SqlCommand ( command , conn ) ;
290+ if ( async )
291291 {
292- if ( async)
293- {
294- await cmd . ExecuteScalarAsync ( ) ;
295- }
296- else
297- cmd . ExecuteScalar ( ) ;
292+ await cmd . ExecuteScalarAsync ( ) ;
298293 }
294+ else
295+ cmd . ExecuteScalar ( ) ;
299296 }
300297 catch ( Exception ex )
301298 {
@@ -326,22 +323,15 @@ private static bool RunSingleStressTest(Action testAction)
326323 return true ;
327324 }
328325
329- private static async Task < bool > TestConnectionPoolExhaustion ( ConnectionPoolStressTest test , bool async )
326+ private static async Task < bool > TestConnectionPoolExhaustion ( string connectionString , int maxPoolSize , bool async )
330327 {
331- // Test Microsoft.Data.SqlClient
332- return await TestConnectionPoolExhaustionForProvider ( test . ConnectionString , test . MaxPoolSize , "Microsoft.Data.SqlClient" , async ,
333- cs => new SqlConnection ( cs ) ) ;
334- }
335-
336- private static async Task < bool > TestConnectionPoolExhaustionForProvider ( string connectionString , int maxPoolSize , string providerName , bool async , Func < string , DbConnection > connectionFactory )
337- {
338- var connections = new List < DbConnection > ( ) ;
328+ var connections = new List < SqlConnection > ( ) ;
339329
340330 try
341331 {
342332 for ( int i = 0 ; i < maxPoolSize ; i ++ )
343333 {
344- var conn = connectionFactory ( connectionString ) ;
334+ SqlConnection conn = new ( connectionString ) ;
345335 if ( async)
346336 {
347337 await conn . OpenAsync ( ) ;
@@ -350,7 +340,7 @@ private static async Task<bool> TestConnectionPoolExhaustionForProvider(string c
350340 conn . Open ( ) ;
351341 connections . Add ( conn ) ;
352342 }
353-
343+ Assert . Equal ( maxPoolSize , connections . Count ) ;
354344 }
355345 catch
356346 {
@@ -359,7 +349,7 @@ private static async Task<bool> TestConnectionPoolExhaustionForProvider(string c
359349 finally
360350 {
361351 // Clean up all connections
362- foreach ( var conn in connections )
352+ foreach ( SqlConnection conn in connections)
363353 {
364354 conn ? . Dispose ( ) ;
365355 }
@@ -392,7 +382,7 @@ public async Task ConnectionPoolStress_Sync()
392382 Assert . Fail ( "ConnectionPoolStress_MsData_Sync failed" ) ;
393383 }
394384
395- if ( ! await TestConnectionPoolExhaustion ( test , false ) )
385+ if ( ! await TestConnectionPoolExhaustion ( test . ConnectionString , test . MaxPoolSize , false ) )
396386 {
397387 // fail the test
398388 Assert . Fail ( "ConnectionPoolStress_MsData_Sync failed" ) ;
@@ -420,8 +410,8 @@ public async Task ConnectionPoolStress_Async()
420410 Assert . Fail ( "ConnectionPoolStress_MsData_Async failed" ) ;
421411 }
422412
423- // Test connection pool exhaustion
424- if ( ! await TestConnectionPoolExhaustion ( test , true ) )
413+ // Test connection pool exhaustion (async)
414+ if ( ! await TestConnectionPoolExhaustion ( test . ConnectionString , test . MaxPoolSize , true ) )
425415 {
426416 // fail the test
427417 Assert . Fail ( "ConnectionPoolStress_MsData_Async failed" ) ;
0 commit comments