@@ -654,50 +654,43 @@ internal void Activate(object owner)
654654
655655 internal bool SetCancelStateClosed ( )
656656 {
657- return Interlocked . CompareExchange ( ref _cancelState , CancelState . Unset , CancelState . Closed ) == CancelState . Unset ;
657+ return Interlocked . CompareExchange ( ref _cancelState , CancelState . Closed , CancelState . Unset ) == CancelState . Unset && _cancelState == CancelState . Closed ;
658658 }
659659
660660 // This method is only called by the command or datareader as a result of a user initiated
661661 // cancel request.
662662 internal void Cancel ( int objectID )
663663 {
664- if (
665- ( _parser . State != TdsParserState . Closed ) && ( _parser . State != TdsParserState . Broken ) &&
666- Interlocked . CompareExchange ( ref _cancelState , CancelState . Unset , CancelState . Cancelled ) == CancelState . Unset
667- )
664+ // only change state if it is Unset, so don't check the return value
665+ Interlocked . CompareExchange ( ref _cancelState , CancelState . Cancelled , CancelState . Unset ) ;
666+
667+ // don't allow objectID -1 since it is reserved for 'not associated with a command'
668+ // yes, the 2^32-1 comand won't cancel - but it also won't cancel when we don't want it
669+ if ( ( _parser . State != TdsParserState . Closed ) && ( _parser . State != TdsParserState . Broken )
670+ && ( objectID == _allowObjectID ) && ( objectID != - 1 ) && _pendingData && ! _attentionSent )
668671 {
669- // don't allow objectID -1 since it is reserved for 'not associated with a command'
670- // yes, the 2^32-1 comand won't cancel - but it also won't cancel when we don't want it
671- if (
672- ( objectID == _allowObjectID ) &&
673- ( objectID != - 1 ) )
672+ bool hasParserLock = false ;
673+ // Keep looping until we have the parser lock (and so are allowed to write), or the conneciton closes\breaks
674+ while ( ( ! hasParserLock ) && ( _parser . State != TdsParserState . Closed ) && ( _parser . State != TdsParserState . Broken ) )
674675 {
675- if ( _pendingData && ! _attentionSent )
676+ try
676677 {
677- bool hasParserLock = false ;
678- // Keep looping until we have the parser lock (and so are allowed to write), or the conneciton closes\breaks
679- while ( ( ! hasParserLock ) && ( _parser . State != TdsParserState . Closed ) && ( _parser . State != TdsParserState . Broken ) )
678+ _parser . Connection . _parserLock . Wait ( canReleaseFromAnyThread : false , timeout : _waitForCancellationLockPollTimeout , lockTaken : ref hasParserLock ) ;
679+ if ( hasParserLock )
680680 {
681- try
682- {
683- _parser . Connection . _parserLock . Wait ( canReleaseFromAnyThread : false , timeout : _waitForCancellationLockPollTimeout , lockTaken : ref hasParserLock ) ;
684- if ( hasParserLock )
685- {
686- _parser . Connection . ThreadHasParserLockForClose = true ;
687- SendAttention ( ) ;
688- }
689- }
690- finally
681+ _parser . Connection . ThreadHasParserLockForClose = true ;
682+ SendAttention ( ) ;
683+ }
684+ }
685+ finally
686+ {
687+ if ( hasParserLock )
688+ {
689+ if ( _parser . Connection . ThreadHasParserLockForClose )
691690 {
692- if ( hasParserLock )
693- {
694- if ( _parser . Connection . ThreadHasParserLockForClose )
695- {
696- _parser . Connection . ThreadHasParserLockForClose = false ;
697- }
698- _parser . Connection . _parserLock . Release ( ) ;
699- }
691+ _parser . Connection . ThreadHasParserLockForClose = false ;
700692 }
693+ _parser . Connection . _parserLock . Release ( ) ;
701694 }
702695 }
703696 }
0 commit comments