@@ -1988,8 +1988,13 @@ private Task WriteRowSourceToServerAsync(int columnCount, CancellationToken ctok
19881988 _parserLock = internalConnection . _parserLock ;
19891989 _parserLock . Wait ( canReleaseFromAnyThread : _isAsyncBulkCopy ) ;
19901990
1991+ TdsParser bestEffortCleanupTarget = null ;
1992+ #if NETFRAMEWORK
1993+ RuntimeHelpers . PrepareConstrainedRegions ( ) ;
1994+ #endif
19911995 try
19921996 {
1997+ bestEffortCleanupTarget = SqlInternalConnection . GetBestEffortCleanupTarget ( _connection ) ;
19931998 WriteRowSourceToServerCommon ( columnCount ) ; // This is common in both sync and async
19941999 Task resultTask = WriteToServerInternalAsync ( ctoken ) ; // resultTask is null for sync, but Task for async.
19952000 if ( resultTask != null )
@@ -2037,6 +2042,9 @@ private Task WriteRowSourceToServerAsync(int columnCount, CancellationToken ctok
20372042 catch ( System . Threading . ThreadAbortException e )
20382043 {
20392044 _connection . Abort ( e ) ;
2045+ #if NETFRAMEWORK
2046+ SqlInternalConnection . BestEffortCleanup ( bestEffortCleanupTarget ) ;
2047+ #endif
20402048 throw ;
20412049 }
20422050 finally
@@ -2297,7 +2305,8 @@ private void CopyColumnsAsyncSetupContinuation(TaskCompletionSource<object> sour
22972305 {
22982306 source . SetResult ( null ) ;
22992307 }
2300- }
2308+ } ,
2309+ connectionToDoom : _connection . GetOpenTdsConnection ( )
23012310 ) ;
23022311 }
23032312
@@ -2434,8 +2443,8 @@ private Task CopyRowsAsync(int rowsSoFar, int totalRows, CancellationToken cts,
24342443 resultTask = source . Task ;
24352444
24362445 AsyncHelper . ContinueTaskWithState ( readTask , source , this ,
2437- onSuccess : ( object state ) => ( ( SqlBulkCopy ) state ) . CopyRowsAsync ( i + 1 , totalRows , cts , source )
2438-
2446+ onSuccess : ( object state ) => ( ( SqlBulkCopy ) state ) . CopyRowsAsync ( i + 1 , totalRows , cts , source ) ,
2447+ connectionToDoom : _connection . GetOpenTdsConnection ( )
24392448 ) ;
24402449 return resultTask ; // Associated task will be completed when all rows are copied to server/exception/cancelled.
24412450 }
@@ -2459,12 +2468,14 @@ private Task CopyRowsAsync(int rowsSoFar, int totalRows, CancellationToken cts,
24592468 else
24602469 {
24612470 AsyncHelper . ContinueTaskWithState ( readTask , source , sqlBulkCopy ,
2462- onSuccess : ( object state2 ) => ( ( SqlBulkCopy ) state2 ) . CopyRowsAsync ( i + 1 , totalRows , cts , source )
2471+ onSuccess : ( object state2 ) => ( ( SqlBulkCopy ) state2 ) . CopyRowsAsync ( i + 1 , totalRows , cts , source ) ,
2472+ connectionToDoom : _connection . GetOpenTdsConnection ( )
24632473 ) ;
24642474 }
2465- }
2466- ) ;
2467- return resultTask ;
2475+ } ,
2476+ connectionToDoom : _connection . GetOpenTdsConnection ( )
2477+ ) ;
2478+ return resultTask ;
24682479 }
24692480 }
24702481
@@ -2542,7 +2553,8 @@ private Task CopyBatchesAsync(BulkCopySimpleResultSet internalResults, string up
25422553 // Continuation finished sync, recall into CopyBatchesAsync to continue
25432554 sqlBulkCopy . CopyBatchesAsync ( internalResults , updateBulkCommandText , cts , source ) ;
25442555 }
2545- }
2556+ } ,
2557+ connectionToDoom : _connection . GetOpenTdsConnection ( )
25462558 ) ;
25472559 return source . Task ;
25482560 }
@@ -2609,7 +2621,8 @@ private Task CopyBatchesAsyncContinued(BulkCopySimpleResultSet internalResults,
26092621 }
26102622 } ,
26112623 onFailure : static ( Exception _ , object state ) => ( ( SqlBulkCopy ) state ) . CopyBatchesAsyncContinuedOnError ( cleanupParser : false ) ,
2612- onCancellation : static ( object state ) => ( ( SqlBulkCopy ) state ) . CopyBatchesAsyncContinuedOnError ( cleanupParser : true )
2624+ onCancellation : static ( object state ) => ( ( SqlBulkCopy ) state ) . CopyBatchesAsyncContinuedOnError ( cleanupParser : true ) ,
2625+ connectionToDoom : _connection . GetOpenTdsConnection ( )
26132626 ) ;
26142627
26152628 return source . Task ;
@@ -2675,7 +2688,8 @@ private Task CopyBatchesAsyncContinuedOnSuccess(BulkCopySimpleResultSet internal
26752688 // Always call back into CopyBatchesAsync
26762689 sqlBulkCopy . CopyBatchesAsync ( internalResults , updateBulkCommandText , cts , source ) ;
26772690 } ,
2678- onFailure : static ( Exception _ , object state ) => ( ( SqlBulkCopy ) state ) . CopyBatchesAsyncContinuedOnError ( cleanupParser : false )
2691+ onFailure : static ( Exception _ , object state ) => ( ( SqlBulkCopy ) state ) . CopyBatchesAsyncContinuedOnError ( cleanupParser : false ) ,
2692+ connectionToDoom : _connection . GetOpenTdsConnection ( )
26792693 ) ;
26802694 return source . Task ;
26812695 }
@@ -2698,6 +2712,9 @@ private Task CopyBatchesAsyncContinuedOnSuccess(BulkCopySimpleResultSet internal
26982712 private void CopyBatchesAsyncContinuedOnError ( bool cleanupParser )
26992713 {
27002714 SqlInternalConnectionTds internalConnection = _connection . GetOpenTdsConnection ( ) ;
2715+ #if NETFRAMEWORK
2716+ RuntimeHelpers . PrepareConstrainedRegions ( ) ;
2717+ #endif
27012718 try
27022719 {
27032720 if ( ( cleanupParser ) & & ( _parser != null ) && ( _stateObj != null ) )
@@ -2838,7 +2855,8 @@ private void WriteToServerInternalRestContinuedAsync(BulkCopySimpleResultSet int
28382855 }
28392856 }
28402857 }
2841- }
2858+ } ,
2859+ connectionToDoom : _connection . GetOpenTdsConnection ( )
28422860 ) ;
28432861 return ;
28442862 }
@@ -2957,6 +2975,7 @@ private void WriteToServerInternalRestAsync(CancellationToken cts, TaskCompletio
29572975 _parserLock . Wait ( canReleaseFromAnyThread : true ) ;
29582976 WriteToServerInternalRestAsync ( cts , source ) ;
29592977 } ,
2978+ connectionToAbort : _connection ,
29602979 onFailure : static ( Exception _ , object state ) => ( ( StrongBox < CancellationTokenRegistration > ) state ) . Value . Dispose ( ) ,
29612980 onCancellation : static ( object state ) => ( ( StrongBox < CancellationTokenRegistration > ) state ) . Value . Dispose ( ) ,
29622981 exceptionConverter : ( ex ) => SQL . BulkLoadInvalidDestinationTable ( _destinationTableName , ex ) ) ;
@@ -3008,7 +3027,8 @@ private void WriteToServerInternalRestAsync(CancellationToken cts, TaskCompletio
30083027 if ( internalResultsTask != null )
30093028 {
30103029 AsyncHelper . ContinueTaskWithState ( internalResultsTask , source , this ,
3011- onSuccess : ( object state ) => ( ( SqlBulkCopy ) state ) . WriteToServerInternalRestContinuedAsync ( internalResultsTask . Result , cts , source )
3030+ onSuccess : ( object state ) => ( ( SqlBulkCopy ) state ) . WriteToServerInternalRestContinuedAsync ( internalResultsTask . Result , cts , source ) ,
3031+ connectionToDoom : _connection . GetOpenTdsConnection ( )
30123032 ) ;
30133033 }
30143034 else
@@ -3092,7 +3112,8 @@ private Task WriteToServerInternalAsync(CancellationToken ctoken)
30923112 {
30933113 sqlBulkCopy . WriteToServerInternalRestAsync ( ctoken , source ) ; // Passing the same completion which will be completed by the Callee.
30943114 }
3095- }
3115+ } ,
3116+ connectionToDoom : _connection . GetOpenTdsConnection ( )
30963117 ) ;
30973118 return resultTask ;
30983119 }
0 commit comments