@@ -235,6 +235,8 @@ internal bool IsActiveConnectionValid(SqlConnection activeConnection)
235235
236236 internal void ResetAsyncState ( )
237237 {
238+ SqlClientEventSource . Log . TryTraceEvent ( "CachedAsyncState.ResetAsyncState | API | ObjectId {0}, Client Connection Id {1}, AsyncCommandInProgress={2}" ,
239+ _cachedAsyncConnection ? . ObjectID , _cachedAsyncConnection ? . ClientConnectionId , _cachedAsyncConnection ? . AsyncCommandInProgress ) ;
238240 _cachedAsyncCloseCount = - 1 ;
239241 _cachedAsyncResult = null ;
240242 if ( _cachedAsyncConnection != null )
@@ -252,6 +254,7 @@ internal void SetActiveConnectionAndResult(TaskCompletionSource<object> completi
252254 {
253255 Debug . Assert ( activeConnection != null , "Unexpected null connection argument on SetActiveConnectionAndResult!" ) ;
254256 TdsParser parser = activeConnection ? . Parser ;
257+ SqlClientEventSource . Log . TryTraceEvent ( "SqlCommand.SetActiveConnectionAndResult | API | ObjectId {0}, Client Connection Id {1}, MARS={2}" , activeConnection ? . ObjectID , activeConnection ? . ClientConnectionId , parser ? . MARSOn ) ;
255258 if ( ( parser == null ) || ( parser . State == TdsParserState . Closed ) || ( parser . State == TdsParserState . Broken ) )
256259 {
257260 throw ADP . ClosedConnectionError ( ) ;
@@ -972,8 +975,12 @@ override protected DbParameter CreateDbParameter()
972975 override protected void Dispose ( bool disposing )
973976 {
974977 if ( disposing )
975- { // release managed objects
978+ {
979+ // release managed objects
976980 _cachedMetaData = null ;
981+
982+ // reset async cache information to allow a second async execute
983+ _cachedAsyncState ? . ResetAsyncState ( ) ;
977984 }
978985 // release unmanaged objects
979986 base . Dispose ( disposing ) ;
@@ -1213,14 +1220,23 @@ private void BeginExecuteNonQueryInternalReadStage(TaskCompletionSource<object>
12131220 cachedAsyncState . SetActiveConnectionAndResult ( completion , nameof ( EndExecuteNonQuery ) , _activeConnection ) ;
12141221 _stateObj . ReadSni ( completion ) ;
12151222 }
1223+ // Cause of a possible unstable runtime situation on facing with `OutOfMemoryException` and `StackOverflowException` exceptions,
1224+ // trying to call further functions in the catch of either may fail that should be considered on debuging!
1225+ catch ( System . OutOfMemoryException e )
1226+ {
1227+ _activeConnection . Abort ( e ) ;
1228+ throw ;
1229+ }
1230+ catch ( System . StackOverflowException e )
1231+ {
1232+ _activeConnection . Abort ( e ) ;
1233+ throw ;
1234+ }
12161235 catch ( Exception )
12171236 {
12181237 // Similarly, if an exception occurs put the stateObj back into the pool.
12191238 // and reset async cache information to allow a second async execute
1220- if ( null != _cachedAsyncState )
1221- {
1222- _cachedAsyncState . ResetAsyncState ( ) ;
1223- }
1239+ _cachedAsyncState ? . ResetAsyncState ( ) ;
12241240 ReliablePutStateObject ( ) ;
12251241 throw ;
12261242 }
@@ -1229,7 +1245,9 @@ private void BeginExecuteNonQueryInternalReadStage(TaskCompletionSource<object>
12291245 private void VerifyEndExecuteState ( Task completionTask , string endMethod , bool fullCheckForColumnEncryption = false )
12301246 {
12311247 Debug . Assert ( completionTask != null ) ;
1232-
1248+ SqlClientEventSource . Log . TryTraceEvent ( "SqlCommand.VerifyEndExecuteState | API | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}" ,
1249+ _activeConnection ? . ObjectID , _activeConnection ? . ClientConnectionId ,
1250+ _activeConnection ? . Parser ? . MARSOn , _activeConnection ? . AsyncCommandInProgress ) ;
12331251 if ( completionTask . IsCanceled )
12341252 {
12351253 if ( _stateObj != null )
@@ -1336,10 +1354,7 @@ public int EndExecuteNonQueryAsync(IAsyncResult asyncResult)
13361354 if ( asyncException != null )
13371355 {
13381356 // Leftover exception from the Begin...InternalReadStage
1339- if ( cachedAsyncState != null )
1340- {
1341- cachedAsyncState . ResetAsyncState ( ) ;
1342- }
1357+ cachedAsyncState ? . ResetAsyncState ( ) ;
13431358 ReliablePutStateObject ( ) ;
13441359 throw asyncException . InnerException ;
13451360 }
@@ -1402,6 +1417,9 @@ private int EndExecuteNonQueryInternal(IAsyncResult asyncResult)
14021417
14031418 private object InternalEndExecuteNonQuery ( IAsyncResult asyncResult , bool isInternal , [ CallerMemberName ] string endMethod = "" )
14041419 {
1420+ SqlClientEventSource . Log . TryTraceEvent ( "SqlCommand.InternalEndExecuteNonQuery | INFO | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}" ,
1421+ _activeConnection ? . ObjectID , _activeConnection ? . ClientConnectionId ,
1422+ _activeConnection ? . Parser ? . MARSOn , _activeConnection ? . AsyncCommandInProgress ) ;
14051423 VerifyEndExecuteState ( ( Task ) asyncResult , endMethod ) ;
14061424 WaitForAsyncResults ( asyncResult , isInternal ) ;
14071425
@@ -1486,6 +1504,8 @@ private object InternalEndExecuteNonQuery(IAsyncResult asyncResult, bool isInter
14861504
14871505 private Task InternalExecuteNonQuery ( TaskCompletionSource < object > completion , bool sendToPipe , int timeout , out bool usedCache , bool asyncWrite = false , bool inRetry = false , [ CallerMemberName ] string methodName = "" )
14881506 {
1507+ SqlClientEventSource . Log . TryTraceEvent ( "SqlCommand.InternalExecuteNonQuery | INFO | ObjectId {0}, Client Connection Id {1}, AsyncCommandInProgress={2}" ,
1508+ _activeConnection ? . ObjectID , _activeConnection ? . ClientConnectionId , _activeConnection ? . AsyncCommandInProgress ) ;
14891509 bool isAsync = ( null != completion ) ;
14901510 usedCache = false ;
14911511
@@ -1716,14 +1736,25 @@ private void BeginExecuteXmlReaderInternalReadStage(TaskCompletionSource<object>
17161736 _cachedAsyncState . SetActiveConnectionAndResult ( completion , nameof ( EndExecuteXmlReader ) , _activeConnection ) ;
17171737 _stateObj . ReadSni ( completion ) ;
17181738 }
1739+ // Cause of a possible unstable runtime situation on facing with `OutOfMemoryException` and `StackOverflowException` exceptions,
1740+ // trying to call further functions in the catch of either may fail that should be considered on debuging!
1741+ catch ( System . OutOfMemoryException e )
1742+ {
1743+ _activeConnection . Abort ( e ) ;
1744+ completion . TrySetException ( e ) ;
1745+ throw ;
1746+ }
1747+ catch ( System . StackOverflowException e )
1748+ {
1749+ _activeConnection . Abort ( e ) ;
1750+ completion . TrySetException ( e ) ;
1751+ throw ;
1752+ }
17191753 catch ( Exception e )
17201754 {
17211755 // Similarly, if an exception occurs put the stateObj back into the pool.
17221756 // and reset async cache information to allow a second async execute
1723- if ( null != _cachedAsyncState )
1724- {
1725- _cachedAsyncState . ResetAsyncState ( ) ;
1726- }
1757+ _cachedAsyncState ? . ResetAsyncState ( ) ;
17271758 ReliablePutStateObject ( ) ;
17281759 completion . TrySetException ( e ) ;
17291760 }
@@ -1750,6 +1781,7 @@ private XmlReader EndExecuteXmlReaderAsync(IAsyncResult asyncResult)
17501781 Exception asyncException = ( ( Task ) asyncResult ) . Exception ;
17511782 if ( asyncException != null )
17521783 {
1784+ cachedAsyncState ? . ResetAsyncState ( ) ;
17531785 ReliablePutStateObject ( ) ;
17541786 throw asyncException . InnerException ;
17551787 }
@@ -1944,6 +1976,7 @@ internal SqlDataReader EndExecuteReaderAsync(IAsyncResult asyncResult)
19441976 Exception asyncException = ( ( Task ) asyncResult ) . Exception ;
19451977 if ( asyncException != null )
19461978 {
1979+ cachedAsyncState ? . ResetAsyncState ( ) ;
19471980 ReliablePutStateObject ( ) ;
19481981 throw asyncException . InnerException ;
19491982 }
@@ -1967,6 +2000,9 @@ internal SqlDataReader EndExecuteReaderAsync(IAsyncResult asyncResult)
19672000
19682001 private SqlDataReader EndExecuteReaderInternal ( IAsyncResult asyncResult )
19692002 {
2003+ SqlClientEventSource . Log . TryTraceEvent ( "SqlCommand.EndExecuteReaderInternal | API | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}" ,
2004+ _activeConnection ? . ObjectID , _activeConnection ? . ClientConnectionId ,
2005+ _activeConnection ? . Parser ? . MARSOn , _activeConnection ? . AsyncCommandInProgress ) ;
19702006 SqlStatistics statistics = null ;
19712007 bool success = false ;
19722008 int ? sqlExceptionNumber = null ;
@@ -2337,28 +2373,43 @@ long firstAttemptStart
23372373 private void BeginExecuteReaderInternalReadStage ( TaskCompletionSource < object > completion )
23382374 {
23392375 Debug . Assert ( completion != null , "CompletionSource should not be null" ) ;
2376+ 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 ) ;
23402377 // Read SNI does not have catches for async exceptions, handle here.
23412378 try
23422379 {
23432380 // must finish caching information before ReadSni which can activate the callback before returning
23442381 cachedAsyncState . SetActiveConnectionAndResult ( completion , nameof ( EndExecuteReader ) , _activeConnection ) ;
23452382 _stateObj . ReadSni ( completion ) ;
23462383 }
2384+ // Cause of a possible unstable runtime situation on facing with `OutOfMemoryException` and `StackOverflowException` exceptions,
2385+ // trying to call further functions in the catch of either may fail that should be considered on debuging!
2386+ catch ( System . OutOfMemoryException e )
2387+ {
2388+ _activeConnection . Abort ( e ) ;
2389+ completion . TrySetException ( e ) ;
2390+ throw ;
2391+ }
2392+ catch ( System . StackOverflowException e )
2393+ {
2394+ _activeConnection . Abort ( e ) ;
2395+ completion . TrySetException ( e ) ;
2396+ throw ;
2397+ }
23472398 catch ( Exception e )
23482399 {
23492400 // Similarly, if an exception occurs put the stateObj back into the pool.
23502401 // and reset async cache information to allow a second async execute
2351- if ( null != _cachedAsyncState )
2352- {
2353- _cachedAsyncState . ResetAsyncState ( ) ;
2354- }
2402+ _cachedAsyncState ? . ResetAsyncState ( ) ;
23552403 ReliablePutStateObject ( ) ;
23562404 completion . TrySetException ( e ) ;
23572405 }
23582406 }
23592407
23602408 private SqlDataReader InternalEndExecuteReader ( IAsyncResult asyncResult , bool isInternal , string endMethod )
23612409 {
2410+ SqlClientEventSource . Log . TryTraceEvent ( "SqlCommand.InternalEndExecuteReader | INFO | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}" ,
2411+ _activeConnection ? . ObjectID , _activeConnection ? . ClientConnectionId ,
2412+ _activeConnection ? . Parser ? . MARSOn , _activeConnection ? . AsyncCommandInProgress ) ;
23622413 VerifyEndExecuteState ( ( Task ) asyncResult , endMethod ) ;
23632414 WaitForAsyncResults ( asyncResult , isInternal ) ;
23642415
0 commit comments