@@ -253,6 +253,9 @@ internal bool IsActiveConnectionValid(SqlConnection activeConnection)
253253
254254 internal void ResetAsyncState ( )
255255 {
256+ SqlClientEventSource . Log . TryTraceEvent ( "CachedAsyncState.ResetAsyncState | API | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}" ,
257+ _cachedAsyncConnection ? . ObjectID , _cachedAsyncConnection ? . ClientConnectionId ,
258+ _cachedAsyncConnection ? . Parser ? . MARSOn , _cachedAsyncConnection ? . AsyncCommandInProgress ) ;
256259 _cachedAsyncCloseCount = - 1 ;
257260 _cachedAsyncResult = null ;
258261 if ( _cachedAsyncConnection != null )
@@ -270,6 +273,7 @@ internal void SetActiveConnectionAndResult(TaskCompletionSource<object> completi
270273 {
271274 Debug . Assert ( activeConnection != null , "Unexpected null connection argument on SetActiveConnectionAndResult!" ) ;
272275 TdsParser parser = activeConnection ? . Parser ;
276+ SqlClientEventSource . Log . TryTraceEvent ( "SqlCommand.SetActiveConnectionAndResult | API | ObjectId {0}, Client Connection Id {1}, MARS={2}" , activeConnection ? . ObjectID , activeConnection ? . ClientConnectionId , parser ? . MARSOn ) ;
273277 if ( ( parser == null ) || ( parser . State == TdsParserState . Closed ) || ( parser . State == TdsParserState . Broken ) )
274278 {
275279 throw ADP . ClosedConnectionError ( ) ;
@@ -1011,8 +1015,12 @@ protected override DbParameter CreateDbParameter()
10111015 protected override void Dispose ( bool disposing )
10121016 {
10131017 if ( disposing )
1014- { // release managed objects
1018+ {
1019+ // release managed objects
10151020 _cachedMetaData = null ;
1021+
1022+ // reset async cache information to allow a second async execute
1023+ _cachedAsyncState ? . ResetAsyncState ( ) ;
10161024 }
10171025 // release unmanaged objects
10181026 base . Dispose ( disposing ) ;
@@ -1271,14 +1279,22 @@ private void BeginExecuteNonQueryInternalReadStage(TaskCompletionSource<object>
12711279 cachedAsyncState . SetActiveConnectionAndResult ( completion , nameof ( EndExecuteNonQuery ) , _activeConnection ) ;
12721280 _stateObj . ReadSni ( completion ) ;
12731281 }
1282+
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+ }
12741293 catch ( Exception )
12751294 {
12761295 // Similarly, if an exception occurs put the stateObj back into the pool.
12771296 // and reset async cache information to allow a second async execute
1278- if ( null != _cachedAsyncState )
1279- {
1280- _cachedAsyncState . ResetAsyncState ( ) ;
1281- }
1297+ _cachedAsyncState ? . ResetAsyncState ( ) ;
12821298 ReliablePutStateObject ( ) ;
12831299 throw ;
12841300 }
@@ -1287,7 +1303,9 @@ private void BeginExecuteNonQueryInternalReadStage(TaskCompletionSource<object>
12871303 private void VerifyEndExecuteState ( Task completionTask , string endMethod , bool fullCheckForColumnEncryption = false )
12881304 {
12891305 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 ) ;
12911309 if ( completionTask . IsCanceled )
12921310 {
12931311 if ( _stateObj != null )
@@ -1460,6 +1478,9 @@ private int EndExecuteNonQueryInternal(IAsyncResult asyncResult)
14601478
14611479 private object InternalEndExecuteNonQuery ( IAsyncResult asyncResult , bool isInternal , [ CallerMemberName ] string endMethod = "" )
14621480 {
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 ) ;
14631484 VerifyEndExecuteState ( ( Task ) asyncResult , endMethod ) ;
14641485 WaitForAsyncResults ( asyncResult , isInternal ) ;
14651486
@@ -1544,6 +1565,8 @@ private object InternalEndExecuteNonQuery(IAsyncResult asyncResult, bool isInter
15441565
15451566 private Task InternalExecuteNonQuery ( TaskCompletionSource < object > completion , bool sendToPipe , int timeout , out bool usedCache , bool asyncWrite = false , bool inRetry = false , [ CallerMemberName ] string methodName = "" )
15461567 {
1568+ SqlClientEventSource . Log . TryTraceEvent ( "SqlCommand.InternalExecuteNonQuery | INFO | ObjectId {0}, Client Connection Id {1}, AsyncCommandInProgress={2}" ,
1569+ _activeConnection ? . ObjectID , _activeConnection ? . ClientConnectionId , _activeConnection ? . AsyncCommandInProgress ) ;
15471570 bool isAsync = ( null != completion ) ;
15481571 usedCache = false ;
15491572
@@ -1780,14 +1803,23 @@ private void BeginExecuteXmlReaderInternalReadStage(TaskCompletionSource<object>
17801803 _cachedAsyncState . SetActiveConnectionAndResult ( completion , nameof ( EndExecuteXmlReader ) , _activeConnection ) ;
17811804 _stateObj . ReadSni ( completion ) ;
17821805 }
1806+ catch ( System . OutOfMemoryException e )
1807+ {
1808+ _activeConnection . Abort ( e ) ;
1809+ completion . TrySetException ( e ) ;
1810+ throw ;
1811+ }
1812+ catch ( System . StackOverflowException e )
1813+ {
1814+ _activeConnection . Abort ( e ) ;
1815+ completion . TrySetException ( e ) ;
1816+ throw ;
1817+ }
17831818 catch ( Exception e )
17841819 {
17851820 // Similarly, if an exception occurs put the stateObj back into the pool.
17861821 // and reset async cache information to allow a second async execute
1787- if ( null != _cachedAsyncState )
1788- {
1789- _cachedAsyncState . ResetAsyncState ( ) ;
1790- }
1822+ _cachedAsyncState ? . ResetAsyncState ( ) ;
17911823 ReliablePutStateObject ( ) ;
17921824 completion . TrySetException ( e ) ;
17931825 }
@@ -2034,6 +2066,9 @@ internal SqlDataReader EndExecuteReaderAsync(IAsyncResult asyncResult)
20342066
20352067 private SqlDataReader EndExecuteReaderInternal ( IAsyncResult asyncResult )
20362068 {
2069+ SqlClientEventSource . Log . TryTraceEvent ( "SqlCommand.EndExecuteReaderInternal | API | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}" ,
2070+ _activeConnection ? . ObjectID , _activeConnection ? . ClientConnectionId ,
2071+ _activeConnection ? . Parser ? . MARSOn , _activeConnection ? . AsyncCommandInProgress ) ;
20372072 SqlStatistics statistics = null ;
20382073 bool success = false ;
20392074 int ? sqlExceptionNumber = null ;
@@ -2404,28 +2439,41 @@ long firstAttemptStart
24042439 private void BeginExecuteReaderInternalReadStage ( TaskCompletionSource < object > completion )
24052440 {
24062441 Debug . Assert ( completion != null , "CompletionSource should not be null" ) ;
2442+ 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 ) ;
24072443 // Read SNI does not have catches for async exceptions, handle here.
24082444 try
24092445 {
24102446 // must finish caching information before ReadSni which can activate the callback before returning
24112447 cachedAsyncState . SetActiveConnectionAndResult ( completion , nameof ( EndExecuteReader ) , _activeConnection ) ;
24122448 _stateObj . ReadSni ( completion ) ;
24132449 }
2450+ catch ( System . OutOfMemoryException e )
2451+ {
2452+ _activeConnection . Abort ( e ) ;
2453+ completion . TrySetException ( e ) ;
2454+ throw ;
2455+ }
2456+ catch ( System . StackOverflowException e )
2457+ {
2458+ _activeConnection . Abort ( e ) ;
2459+ completion . TrySetException ( e ) ;
2460+ throw ;
2461+ }
24142462 catch ( Exception e )
24152463 {
24162464 // Similarly, if an exception occurs put the stateObj back into the pool.
24172465 // and reset async cache information to allow a second async execute
2418- if ( null != _cachedAsyncState )
2419- {
2420- _cachedAsyncState . ResetAsyncState ( ) ;
2421- }
2466+ _cachedAsyncState ? . ResetAsyncState ( ) ;
24222467 ReliablePutStateObject ( ) ;
24232468 completion . TrySetException ( e ) ;
24242469 }
24252470 }
24262471
24272472 private SqlDataReader InternalEndExecuteReader ( IAsyncResult asyncResult , bool isInternal , string endMethod )
24282473 {
2474+ SqlClientEventSource . Log . TryTraceEvent ( "SqlCommand.InternalEndExecuteReader | INFO | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}" ,
2475+ _activeConnection ? . ObjectID , _activeConnection ? . ClientConnectionId ,
2476+ _activeConnection ? . Parser ? . MARSOn , _activeConnection ? . AsyncCommandInProgress ) ;
24292477 VerifyEndExecuteState ( ( Task ) asyncResult , endMethod ) ;
24302478 WaitForAsyncResults ( asyncResult , isInternal ) ;
24312479
0 commit comments