@@ -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,9 @@ 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}, MARS={2}, AsyncCommandInProgress={3}" ,
1569+ _activeConnection ? . ObjectID , _activeConnection ? . ClientConnectionId ,
1570+ _activeConnection ? . Parser ? . MARSOn , _activeConnection ? . AsyncCommandInProgress ) ;
15471571 bool isAsync = ( null != completion ) ;
15481572 usedCache = false ;
15491573
@@ -1780,14 +1804,23 @@ private void BeginExecuteXmlReaderInternalReadStage(TaskCompletionSource<object>
17801804 _cachedAsyncState . SetActiveConnectionAndResult ( completion , nameof ( EndExecuteXmlReader ) , _activeConnection ) ;
17811805 _stateObj . ReadSni ( completion ) ;
17821806 }
1807+ catch ( System . OutOfMemoryException e )
1808+ {
1809+ _activeConnection . Abort ( e ) ;
1810+ completion . TrySetException ( e ) ;
1811+ throw ;
1812+ }
1813+ catch ( System . StackOverflowException e )
1814+ {
1815+ _activeConnection . Abort ( e ) ;
1816+ completion . TrySetException ( e ) ;
1817+ throw ;
1818+ }
17831819 catch ( Exception e )
17841820 {
17851821 // Similarly, if an exception occurs put the stateObj back into the pool.
17861822 // and reset async cache information to allow a second async execute
1787- if ( null != _cachedAsyncState )
1788- {
1789- _cachedAsyncState . ResetAsyncState ( ) ;
1790- }
1823+ _cachedAsyncState ? . ResetAsyncState ( ) ;
17911824 ReliablePutStateObject ( ) ;
17921825 completion . TrySetException ( e ) ;
17931826 }
@@ -2034,6 +2067,9 @@ internal SqlDataReader EndExecuteReaderAsync(IAsyncResult asyncResult)
20342067
20352068 private SqlDataReader EndExecuteReaderInternal ( IAsyncResult asyncResult )
20362069 {
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 ) ;
20372073 SqlStatistics statistics = null ;
20382074 bool success = false ;
20392075 int ? sqlExceptionNumber = null ;
@@ -2404,28 +2440,41 @@ long firstAttemptStart
24042440 private void BeginExecuteReaderInternalReadStage ( TaskCompletionSource < object > completion )
24052441 {
24062442 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 ) ;
24072444 // Read SNI does not have catches for async exceptions, handle here.
24082445 try
24092446 {
24102447 // must finish caching information before ReadSni which can activate the callback before returning
24112448 cachedAsyncState . SetActiveConnectionAndResult ( completion , nameof ( EndExecuteReader ) , _activeConnection ) ;
24122449 _stateObj . ReadSni ( completion ) ;
24132450 }
2451+ catch ( System . OutOfMemoryException e )
2452+ {
2453+ _activeConnection . Abort ( e ) ;
2454+ completion . TrySetException ( e ) ;
2455+ throw ;
2456+ }
2457+ catch ( System . StackOverflowException e )
2458+ {
2459+ _activeConnection . Abort ( e ) ;
2460+ completion . TrySetException ( e ) ;
2461+ throw ;
2462+ }
24142463 catch ( Exception e )
24152464 {
24162465 // Similarly, if an exception occurs put the stateObj back into the pool.
24172466 // and reset async cache information to allow a second async execute
2418- if ( null != _cachedAsyncState )
2419- {
2420- _cachedAsyncState . ResetAsyncState ( ) ;
2421- }
2467+ _cachedAsyncState ? . ResetAsyncState ( ) ;
24222468 ReliablePutStateObject ( ) ;
24232469 completion . TrySetException ( e ) ;
24242470 }
24252471 }
24262472
24272473 private SqlDataReader InternalEndExecuteReader ( IAsyncResult asyncResult , bool isInternal , string endMethod )
24282474 {
2475+ SqlClientEventSource . Log . TryTraceEvent ( "SqlCommand.InternalEndExecuteReader | INFO | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}" ,
2476+ _activeConnection ? . ObjectID , _activeConnection ? . ClientConnectionId ,
2477+ _activeConnection ? . Parser ? . MARSOn , _activeConnection ? . AsyncCommandInProgress ) ;
24292478 VerifyEndExecuteState ( ( Task ) asyncResult , endMethod ) ;
24302479 WaitForAsyncResults ( asyncResult , isInternal ) ;
24312480
0 commit comments