@@ -253,6 +253,8 @@ internal bool IsActiveConnectionValid(SqlConnection activeConnection)
253
253
254
254
internal void ResetAsyncState ( )
255
255
{
256
+ SqlClientEventSource . Log . TryTraceEvent ( "CachedAsyncState.ResetAsyncState | API | ObjectId {0}, Client Connection Id {1}, AsyncCommandInProgress={2}" ,
257
+ _cachedAsyncConnection ? . ObjectID , _cachedAsyncConnection ? . ClientConnectionId , _cachedAsyncConnection ? . AsyncCommandInProgress ) ;
256
258
_cachedAsyncCloseCount = - 1 ;
257
259
_cachedAsyncResult = null ;
258
260
if ( _cachedAsyncConnection != null )
@@ -270,6 +272,7 @@ internal void SetActiveConnectionAndResult(TaskCompletionSource<object> completi
270
272
{
271
273
Debug . Assert ( activeConnection != null , "Unexpected null connection argument on SetActiveConnectionAndResult!" ) ;
272
274
TdsParser parser = activeConnection ? . Parser ;
275
+ SqlClientEventSource . Log . TryTraceEvent ( "SqlCommand.SetActiveConnectionAndResult | API | ObjectId {0}, Client Connection Id {1}, MARS={2}" , activeConnection ? . ObjectID , activeConnection ? . ClientConnectionId , parser ? . MARSOn ) ;
273
276
if ( ( parser == null ) || ( parser . State == TdsParserState . Closed ) || ( parser . State == TdsParserState . Broken ) )
274
277
{
275
278
throw ADP . ClosedConnectionError ( ) ;
@@ -1011,8 +1014,12 @@ protected override DbParameter CreateDbParameter()
1011
1014
protected override void Dispose ( bool disposing )
1012
1015
{
1013
1016
if ( disposing )
1014
- { // release managed objects
1017
+ {
1018
+ // release managed objects
1015
1019
_cachedMetaData = null ;
1020
+
1021
+ // reset async cache information to allow a second async execute
1022
+ _cachedAsyncState ? . ResetAsyncState ( ) ;
1016
1023
}
1017
1024
// release unmanaged objects
1018
1025
base . Dispose ( disposing ) ;
@@ -1271,14 +1278,23 @@ private void BeginExecuteNonQueryInternalReadStage(TaskCompletionSource<object>
1271
1278
cachedAsyncState . SetActiveConnectionAndResult ( completion , nameof ( EndExecuteNonQuery ) , _activeConnection ) ;
1272
1279
_stateObj . ReadSni ( completion ) ;
1273
1280
}
1281
+ // Cause of a possible unstable runtime situation on facing with `OutOfMemoryException` and `StackOverflowException` exceptions,
1282
+ // trying to call further functions in the catch of either may fail that should be considered on debuging!
1283
+ catch ( System . OutOfMemoryException e )
1284
+ {
1285
+ _activeConnection . Abort ( e ) ;
1286
+ throw ;
1287
+ }
1288
+ catch ( System . StackOverflowException e )
1289
+ {
1290
+ _activeConnection . Abort ( e ) ;
1291
+ throw ;
1292
+ }
1274
1293
catch ( Exception )
1275
1294
{
1276
1295
// Similarly, if an exception occurs put the stateObj back into the pool.
1277
1296
// and reset async cache information to allow a second async execute
1278
- if ( null != _cachedAsyncState )
1279
- {
1280
- _cachedAsyncState . ResetAsyncState ( ) ;
1281
- }
1297
+ _cachedAsyncState ? . ResetAsyncState ( ) ;
1282
1298
ReliablePutStateObject ( ) ;
1283
1299
throw ;
1284
1300
}
@@ -1287,7 +1303,9 @@ private void BeginExecuteNonQueryInternalReadStage(TaskCompletionSource<object>
1287
1303
private void VerifyEndExecuteState ( Task completionTask , string endMethod , bool fullCheckForColumnEncryption = false )
1288
1304
{
1289
1305
Debug . Assert ( completionTask != null ) ;
1290
-
1306
+ SqlClientEventSource . Log . TryTraceEvent ( "SqlCommand.VerifyEndExecuteState | API | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}" ,
1307
+ _activeConnection ? . ObjectID , _activeConnection ? . ClientConnectionId ,
1308
+ _activeConnection ? . Parser ? . MARSOn , _activeConnection ? . AsyncCommandInProgress ) ;
1291
1309
if ( completionTask . IsCanceled )
1292
1310
{
1293
1311
if ( _stateObj != null )
@@ -1394,10 +1412,7 @@ public int EndExecuteNonQueryAsync(IAsyncResult asyncResult)
1394
1412
if ( asyncException != null )
1395
1413
{
1396
1414
// Leftover exception from the Begin...InternalReadStage
1397
- if ( cachedAsyncState != null )
1398
- {
1399
- cachedAsyncState . ResetAsyncState ( ) ;
1400
- }
1415
+ cachedAsyncState ? . ResetAsyncState ( ) ;
1401
1416
ReliablePutStateObject ( ) ;
1402
1417
throw asyncException . InnerException ;
1403
1418
}
@@ -1460,6 +1475,9 @@ private int EndExecuteNonQueryInternal(IAsyncResult asyncResult)
1460
1475
1461
1476
private object InternalEndExecuteNonQuery ( IAsyncResult asyncResult , bool isInternal , [ CallerMemberName ] string endMethod = "" )
1462
1477
{
1478
+ SqlClientEventSource . Log . TryTraceEvent ( "SqlCommand.InternalEndExecuteNonQuery | INFO | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}" ,
1479
+ _activeConnection ? . ObjectID , _activeConnection ? . ClientConnectionId ,
1480
+ _activeConnection ? . Parser ? . MARSOn , _activeConnection ? . AsyncCommandInProgress ) ;
1463
1481
VerifyEndExecuteState ( ( Task ) asyncResult , endMethod ) ;
1464
1482
WaitForAsyncResults ( asyncResult , isInternal ) ;
1465
1483
@@ -1544,6 +1562,8 @@ private object InternalEndExecuteNonQuery(IAsyncResult asyncResult, bool isInter
1544
1562
1545
1563
private Task InternalExecuteNonQuery ( TaskCompletionSource < object > completion , bool sendToPipe , int timeout , out bool usedCache , bool asyncWrite = false , bool inRetry = false , [ CallerMemberName ] string methodName = "" )
1546
1564
{
1565
+ SqlClientEventSource . Log . TryTraceEvent ( "SqlCommand.InternalExecuteNonQuery | INFO | ObjectId {0}, Client Connection Id {1}, AsyncCommandInProgress={2}" ,
1566
+ _activeConnection ? . ObjectID , _activeConnection ? . ClientConnectionId , _activeConnection ? . AsyncCommandInProgress ) ;
1547
1567
bool isAsync = ( null != completion ) ;
1548
1568
usedCache = false ;
1549
1569
@@ -1780,14 +1800,25 @@ private void BeginExecuteXmlReaderInternalReadStage(TaskCompletionSource<object>
1780
1800
_cachedAsyncState . SetActiveConnectionAndResult ( completion , nameof ( EndExecuteXmlReader ) , _activeConnection ) ;
1781
1801
_stateObj . ReadSni ( completion ) ;
1782
1802
}
1803
+ // Cause of a possible unstable runtime situation on facing with `OutOfMemoryException` and `StackOverflowException` exceptions,
1804
+ // trying to call further functions in the catch of either may fail that should be considered on debuging!
1805
+ catch ( System . OutOfMemoryException e )
1806
+ {
1807
+ _activeConnection . Abort ( e ) ;
1808
+ completion . TrySetException ( e ) ;
1809
+ throw ;
1810
+ }
1811
+ catch ( System . StackOverflowException e )
1812
+ {
1813
+ _activeConnection . Abort ( e ) ;
1814
+ completion . TrySetException ( e ) ;
1815
+ throw ;
1816
+ }
1783
1817
catch ( Exception e )
1784
1818
{
1785
1819
// Similarly, if an exception occurs put the stateObj back into the pool.
1786
1820
// and reset async cache information to allow a second async execute
1787
- if ( null != _cachedAsyncState )
1788
- {
1789
- _cachedAsyncState . ResetAsyncState ( ) ;
1790
- }
1821
+ _cachedAsyncState ? . ResetAsyncState ( ) ;
1791
1822
ReliablePutStateObject ( ) ;
1792
1823
completion . TrySetException ( e ) ;
1793
1824
}
@@ -1814,6 +1845,7 @@ private XmlReader EndExecuteXmlReaderAsync(IAsyncResult asyncResult)
1814
1845
Exception asyncException = ( ( Task ) asyncResult ) . Exception ;
1815
1846
if ( asyncException != null )
1816
1847
{
1848
+ cachedAsyncState ? . ResetAsyncState ( ) ;
1817
1849
ReliablePutStateObject ( ) ;
1818
1850
throw asyncException . InnerException ;
1819
1851
}
@@ -2011,6 +2043,7 @@ internal SqlDataReader EndExecuteReaderAsync(IAsyncResult asyncResult)
2011
2043
Exception asyncException = ( ( Task ) asyncResult ) . Exception ;
2012
2044
if ( asyncException != null )
2013
2045
{
2046
+ cachedAsyncState ? . ResetAsyncState ( ) ;
2014
2047
ReliablePutStateObject ( ) ;
2015
2048
throw asyncException . InnerException ;
2016
2049
}
@@ -2034,6 +2067,9 @@ internal SqlDataReader EndExecuteReaderAsync(IAsyncResult asyncResult)
2034
2067
2035
2068
private SqlDataReader EndExecuteReaderInternal ( IAsyncResult asyncResult )
2036
2069
{
2070
+ SqlClientEventSource . Log . TryTraceEvent ( "SqlCommand.EndExecuteReaderInternal | API | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}" ,
2071
+ _activeConnection ? . ObjectID , _activeConnection ? . ClientConnectionId ,
2072
+ _activeConnection ? . Parser ? . MARSOn , _activeConnection ? . AsyncCommandInProgress ) ;
2037
2073
SqlStatistics statistics = null ;
2038
2074
bool success = false ;
2039
2075
int ? sqlExceptionNumber = null ;
@@ -2404,28 +2440,43 @@ long firstAttemptStart
2404
2440
private void BeginExecuteReaderInternalReadStage ( TaskCompletionSource < object > completion )
2405
2441
{
2406
2442
Debug . Assert ( completion != null , "CompletionSource should not be null" ) ;
2443
+ SqlClientEventSource . Log . TryCorrelationTraceEvent ( "SqlCommand.BeginExecuteReaderInternalReadStage | INFO | Correlation | Object Id {0}, Activity Id {1}, Client Connection Id {2}, Command Text '{3}'" , ObjectID , ActivityCorrelator . Current , Connection ? . ClientConnectionId , CommandText ) ;
2407
2444
// Read SNI does not have catches for async exceptions, handle here.
2408
2445
try
2409
2446
{
2410
2447
// must finish caching information before ReadSni which can activate the callback before returning
2411
2448
cachedAsyncState . SetActiveConnectionAndResult ( completion , nameof ( EndExecuteReader ) , _activeConnection ) ;
2412
2449
_stateObj . ReadSni ( completion ) ;
2413
2450
}
2451
+ // Cause of a possible unstable runtime situation on facing with `OutOfMemoryException` and `StackOverflowException` exceptions,
2452
+ // trying to call further functions in the catch of either may fail that should be considered on debuging!
2453
+ catch ( System . OutOfMemoryException e )
2454
+ {
2455
+ _activeConnection . Abort ( e ) ;
2456
+ completion . TrySetException ( e ) ;
2457
+ throw ;
2458
+ }
2459
+ catch ( System . StackOverflowException e )
2460
+ {
2461
+ _activeConnection . Abort ( e ) ;
2462
+ completion . TrySetException ( e ) ;
2463
+ throw ;
2464
+ }
2414
2465
catch ( Exception e )
2415
2466
{
2416
2467
// Similarly, if an exception occurs put the stateObj back into the pool.
2417
2468
// and reset async cache information to allow a second async execute
2418
- if ( null != _cachedAsyncState )
2419
- {
2420
- _cachedAsyncState . ResetAsyncState ( ) ;
2421
- }
2469
+ _cachedAsyncState ? . ResetAsyncState ( ) ;
2422
2470
ReliablePutStateObject ( ) ;
2423
2471
completion . TrySetException ( e ) ;
2424
2472
}
2425
2473
}
2426
2474
2427
2475
private SqlDataReader InternalEndExecuteReader ( IAsyncResult asyncResult , bool isInternal , string endMethod )
2428
2476
{
2477
+ SqlClientEventSource . Log . TryTraceEvent ( "SqlCommand.InternalEndExecuteReader | INFO | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}" ,
2478
+ _activeConnection ? . ObjectID , _activeConnection ? . ClientConnectionId ,
2479
+ _activeConnection ? . Parser ? . MARSOn , _activeConnection ? . AsyncCommandInProgress ) ;
2429
2480
VerifyEndExecuteState ( ( Task ) asyncResult , endMethod ) ;
2430
2481
WaitForAsyncResults ( asyncResult , isInternal ) ;
2431
2482
0 commit comments