@@ -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 ( ) ;
@@ -1014,8 +1017,12 @@ protected override DbParameter CreateDbParameter()
1014
1017
protected override void Dispose ( bool disposing )
1015
1018
{
1016
1019
if ( disposing )
1017
- { // release managed objects
1020
+ {
1021
+ // release managed objects
1018
1022
_cachedMetaData = null ;
1023
+
1024
+ // reset async cache information to allow a second async execute
1025
+ _cachedAsyncState ? . ResetAsyncState ( ) ;
1019
1026
}
1020
1027
// release unmanaged objects
1021
1028
base . Dispose ( disposing ) ;
@@ -1274,14 +1281,23 @@ private void BeginExecuteNonQueryInternalReadStage(TaskCompletionSource<object>
1274
1281
cachedAsyncState . SetActiveConnectionAndResult ( completion , nameof ( EndExecuteNonQuery ) , _activeConnection ) ;
1275
1282
_stateObj . ReadSni ( completion ) ;
1276
1283
}
1284
+ // Cause of a possible unstable runtime situation on facing with `OutOfMemoryException` and `StackOverflowException` exceptions,
1285
+ // trying to call further functions in the catch of either may fail that should be considered on debuging!
1286
+ catch ( System . OutOfMemoryException e )
1287
+ {
1288
+ _activeConnection . Abort ( e ) ;
1289
+ throw ;
1290
+ }
1291
+ catch ( System . StackOverflowException e )
1292
+ {
1293
+ _activeConnection . Abort ( e ) ;
1294
+ throw ;
1295
+ }
1277
1296
catch ( Exception )
1278
1297
{
1279
1298
// Similarly, if an exception occurs put the stateObj back into the pool.
1280
1299
// and reset async cache information to allow a second async execute
1281
- if ( null != _cachedAsyncState )
1282
- {
1283
- _cachedAsyncState . ResetAsyncState ( ) ;
1284
- }
1300
+ _cachedAsyncState ? . ResetAsyncState ( ) ;
1285
1301
ReliablePutStateObject ( ) ;
1286
1302
throw ;
1287
1303
}
@@ -1290,7 +1306,9 @@ private void BeginExecuteNonQueryInternalReadStage(TaskCompletionSource<object>
1290
1306
private void VerifyEndExecuteState ( Task completionTask , string endMethod , bool fullCheckForColumnEncryption = false )
1291
1307
{
1292
1308
Debug . Assert ( completionTask != null ) ;
1293
-
1309
+ SqlClientEventSource . Log . TryTraceEvent ( "SqlCommand.VerifyEndExecuteState | API | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}" ,
1310
+ _activeConnection ? . ObjectID , _activeConnection ? . ClientConnectionId ,
1311
+ _activeConnection ? . Parser ? . MARSOn , _activeConnection ? . AsyncCommandInProgress ) ;
1294
1312
if ( completionTask . IsCanceled )
1295
1313
{
1296
1314
if ( _stateObj != null )
@@ -1397,10 +1415,7 @@ public int EndExecuteNonQueryAsync(IAsyncResult asyncResult)
1397
1415
if ( asyncException != null )
1398
1416
{
1399
1417
// Leftover exception from the Begin...InternalReadStage
1400
- if ( cachedAsyncState != null )
1401
- {
1402
- cachedAsyncState . ResetAsyncState ( ) ;
1403
- }
1418
+ cachedAsyncState ? . ResetAsyncState ( ) ;
1404
1419
ReliablePutStateObject ( ) ;
1405
1420
throw asyncException . InnerException ;
1406
1421
}
@@ -1463,6 +1478,9 @@ private int EndExecuteNonQueryInternal(IAsyncResult asyncResult)
1463
1478
1464
1479
private object InternalEndExecuteNonQuery ( IAsyncResult asyncResult , bool isInternal , [ CallerMemberName ] string endMethod = "" )
1465
1480
{
1481
+ SqlClientEventSource . Log . TryTraceEvent ( "SqlCommand.InternalEndExecuteNonQuery | INFO | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}" ,
1482
+ _activeConnection ? . ObjectID , _activeConnection ? . ClientConnectionId ,
1483
+ _activeConnection ? . Parser ? . MARSOn , _activeConnection ? . AsyncCommandInProgress ) ;
1466
1484
VerifyEndExecuteState ( ( Task ) asyncResult , endMethod ) ;
1467
1485
WaitForAsyncResults ( asyncResult , isInternal ) ;
1468
1486
@@ -1547,6 +1565,8 @@ private object InternalEndExecuteNonQuery(IAsyncResult asyncResult, bool isInter
1547
1565
1548
1566
private Task InternalExecuteNonQuery ( TaskCompletionSource < object > completion , bool sendToPipe , int timeout , out bool usedCache , bool asyncWrite = false , bool inRetry = false , [ CallerMemberName ] string methodName = "" )
1549
1567
{
1568
+ SqlClientEventSource . Log . TryTraceEvent ( "SqlCommand.InternalExecuteNonQuery | INFO | ObjectId {0}, Client Connection Id {1}, AsyncCommandInProgress={2}" ,
1569
+ _activeConnection ? . ObjectID , _activeConnection ? . ClientConnectionId , _activeConnection ? . AsyncCommandInProgress ) ;
1550
1570
bool isAsync = ( null != completion ) ;
1551
1571
usedCache = false ;
1552
1572
@@ -1783,14 +1803,25 @@ private void BeginExecuteXmlReaderInternalReadStage(TaskCompletionSource<object>
1783
1803
_cachedAsyncState . SetActiveConnectionAndResult ( completion , nameof ( EndExecuteXmlReader ) , _activeConnection ) ;
1784
1804
_stateObj . ReadSni ( completion ) ;
1785
1805
}
1806
+ // Cause of a possible unstable runtime situation on facing with `OutOfMemoryException` and `StackOverflowException` exceptions,
1807
+ // trying to call further functions in the catch of either may fail that should be considered on debuging!
1808
+ catch ( System . OutOfMemoryException e )
1809
+ {
1810
+ _activeConnection . Abort ( e ) ;
1811
+ completion . TrySetException ( e ) ;
1812
+ throw ;
1813
+ }
1814
+ catch ( System . StackOverflowException e )
1815
+ {
1816
+ _activeConnection . Abort ( e ) ;
1817
+ completion . TrySetException ( e ) ;
1818
+ throw ;
1819
+ }
1786
1820
catch ( Exception e )
1787
1821
{
1788
1822
// Similarly, if an exception occurs put the stateObj back into the pool.
1789
1823
// and reset async cache information to allow a second async execute
1790
- if ( null != _cachedAsyncState )
1791
- {
1792
- _cachedAsyncState . ResetAsyncState ( ) ;
1793
- }
1824
+ _cachedAsyncState ? . ResetAsyncState ( ) ;
1794
1825
ReliablePutStateObject ( ) ;
1795
1826
completion . TrySetException ( e ) ;
1796
1827
}
@@ -1817,6 +1848,7 @@ private XmlReader EndExecuteXmlReaderAsync(IAsyncResult asyncResult)
1817
1848
Exception asyncException = ( ( Task ) asyncResult ) . Exception ;
1818
1849
if ( asyncException != null )
1819
1850
{
1851
+ cachedAsyncState ? . ResetAsyncState ( ) ;
1820
1852
ReliablePutStateObject ( ) ;
1821
1853
throw asyncException . InnerException ;
1822
1854
}
@@ -2014,6 +2046,7 @@ internal SqlDataReader EndExecuteReaderAsync(IAsyncResult asyncResult)
2014
2046
Exception asyncException = ( ( Task ) asyncResult ) . Exception ;
2015
2047
if ( asyncException != null )
2016
2048
{
2049
+ cachedAsyncState ? . ResetAsyncState ( ) ;
2017
2050
ReliablePutStateObject ( ) ;
2018
2051
throw asyncException . InnerException ;
2019
2052
}
@@ -2037,6 +2070,9 @@ internal SqlDataReader EndExecuteReaderAsync(IAsyncResult asyncResult)
2037
2070
2038
2071
private SqlDataReader EndExecuteReaderInternal ( IAsyncResult asyncResult )
2039
2072
{
2073
+ SqlClientEventSource . Log . TryTraceEvent ( "SqlCommand.EndExecuteReaderInternal | API | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}" ,
2074
+ _activeConnection ? . ObjectID , _activeConnection ? . ClientConnectionId ,
2075
+ _activeConnection ? . Parser ? . MARSOn , _activeConnection ? . AsyncCommandInProgress ) ;
2040
2076
SqlStatistics statistics = null ;
2041
2077
bool success = false ;
2042
2078
int ? sqlExceptionNumber = null ;
@@ -2407,28 +2443,43 @@ long firstAttemptStart
2407
2443
private void BeginExecuteReaderInternalReadStage ( TaskCompletionSource < object > completion )
2408
2444
{
2409
2445
Debug . Assert ( completion != null , "CompletionSource should not be null" ) ;
2446
+ 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 ) ;
2410
2447
// Read SNI does not have catches for async exceptions, handle here.
2411
2448
try
2412
2449
{
2413
2450
// must finish caching information before ReadSni which can activate the callback before returning
2414
2451
cachedAsyncState . SetActiveConnectionAndResult ( completion , nameof ( EndExecuteReader ) , _activeConnection ) ;
2415
2452
_stateObj . ReadSni ( completion ) ;
2416
2453
}
2454
+ // Cause of a possible unstable runtime situation on facing with `OutOfMemoryException` and `StackOverflowException` exceptions,
2455
+ // trying to call further functions in the catch of either may fail that should be considered on debuging!
2456
+ catch ( System . OutOfMemoryException e )
2457
+ {
2458
+ _activeConnection . Abort ( e ) ;
2459
+ completion . TrySetException ( e ) ;
2460
+ throw ;
2461
+ }
2462
+ catch ( System . StackOverflowException e )
2463
+ {
2464
+ _activeConnection . Abort ( e ) ;
2465
+ completion . TrySetException ( e ) ;
2466
+ throw ;
2467
+ }
2417
2468
catch ( Exception e )
2418
2469
{
2419
2470
// Similarly, if an exception occurs put the stateObj back into the pool.
2420
2471
// and reset async cache information to allow a second async execute
2421
- if ( null != _cachedAsyncState )
2422
- {
2423
- _cachedAsyncState . ResetAsyncState ( ) ;
2424
- }
2472
+ _cachedAsyncState ? . ResetAsyncState ( ) ;
2425
2473
ReliablePutStateObject ( ) ;
2426
2474
completion . TrySetException ( e ) ;
2427
2475
}
2428
2476
}
2429
2477
2430
2478
private SqlDataReader InternalEndExecuteReader ( IAsyncResult asyncResult , bool isInternal , string endMethod )
2431
2479
{
2480
+ SqlClientEventSource . Log . TryTraceEvent ( "SqlCommand.InternalEndExecuteReader | INFO | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}" ,
2481
+ _activeConnection ? . ObjectID , _activeConnection ? . ClientConnectionId ,
2482
+ _activeConnection ? . Parser ? . MARSOn , _activeConnection ? . AsyncCommandInProgress ) ;
2432
2483
VerifyEndExecuteState ( ( Task ) asyncResult , endMethod ) ;
2433
2484
WaitForAsyncResults ( asyncResult , isInternal ) ;
2434
2485
0 commit comments