@@ -1988,8 +1988,13 @@ private Task WriteRowSourceToServerAsync(int columnCount, CancellationToken ctok
1988
1988
_parserLock = internalConnection . _parserLock ;
1989
1989
_parserLock . Wait ( canReleaseFromAnyThread : _isAsyncBulkCopy ) ;
1990
1990
1991
+ TdsParser bestEffortCleanupTarget = null ;
1992
+ #if NETFRAMEWORK
1993
+ RuntimeHelpers . PrepareConstrainedRegions ( ) ;
1994
+ #endif
1991
1995
try
1992
1996
{
1997
+ bestEffortCleanupTarget = SqlInternalConnection . GetBestEffortCleanupTarget ( _connection ) ;
1993
1998
WriteRowSourceToServerCommon ( columnCount ) ; // This is common in both sync and async
1994
1999
Task resultTask = WriteToServerInternalAsync ( ctoken ) ; // resultTask is null for sync, but Task for async.
1995
2000
if ( resultTask != null )
@@ -2037,6 +2042,9 @@ private Task WriteRowSourceToServerAsync(int columnCount, CancellationToken ctok
2037
2042
catch ( System . Threading . ThreadAbortException e )
2038
2043
{
2039
2044
_connection . Abort ( e ) ;
2045
+ #if NETFRAMEWORK
2046
+ SqlInternalConnection . BestEffortCleanup ( bestEffortCleanupTarget ) ;
2047
+ #endif
2040
2048
throw ;
2041
2049
}
2042
2050
finally
@@ -2297,7 +2305,8 @@ private void CopyColumnsAsyncSetupContinuation(TaskCompletionSource<object> sour
2297
2305
{
2298
2306
source . SetResult ( null ) ;
2299
2307
}
2300
- }
2308
+ } ,
2309
+ connectionToDoom : _connection . GetOpenTdsConnection ( )
2301
2310
) ;
2302
2311
}
2303
2312
@@ -2434,8 +2443,8 @@ private Task CopyRowsAsync(int rowsSoFar, int totalRows, CancellationToken cts,
2434
2443
resultTask = source . Task ;
2435
2444
2436
2445
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 ( )
2439
2448
) ;
2440
2449
return resultTask ; // Associated task will be completed when all rows are copied to server/exception/cancelled.
2441
2450
}
@@ -2459,12 +2468,14 @@ private Task CopyRowsAsync(int rowsSoFar, int totalRows, CancellationToken cts,
2459
2468
else
2460
2469
{
2461
2470
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 ( )
2463
2473
) ;
2464
2474
}
2465
- }
2466
- ) ;
2467
- return resultTask ;
2475
+ } ,
2476
+ connectionToDoom : _connection . GetOpenTdsConnection ( )
2477
+ ) ;
2478
+ return resultTask ;
2468
2479
}
2469
2480
}
2470
2481
@@ -2542,7 +2553,8 @@ private Task CopyBatchesAsync(BulkCopySimpleResultSet internalResults, string up
2542
2553
// Continuation finished sync, recall into CopyBatchesAsync to continue
2543
2554
sqlBulkCopy . CopyBatchesAsync ( internalResults , updateBulkCommandText , cts , source ) ;
2544
2555
}
2545
- }
2556
+ } ,
2557
+ connectionToDoom : _connection . GetOpenTdsConnection ( )
2546
2558
) ;
2547
2559
return source . Task ;
2548
2560
}
@@ -2609,7 +2621,8 @@ private Task CopyBatchesAsyncContinued(BulkCopySimpleResultSet internalResults,
2609
2621
}
2610
2622
} ,
2611
2623
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 ( )
2613
2626
) ;
2614
2627
2615
2628
return source . Task ;
@@ -2675,7 +2688,8 @@ private Task CopyBatchesAsyncContinuedOnSuccess(BulkCopySimpleResultSet internal
2675
2688
// Always call back into CopyBatchesAsync
2676
2689
sqlBulkCopy . CopyBatchesAsync ( internalResults , updateBulkCommandText , cts , source ) ;
2677
2690
} ,
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 ( )
2679
2693
) ;
2680
2694
return source . Task ;
2681
2695
}
@@ -2698,6 +2712,9 @@ private Task CopyBatchesAsyncContinuedOnSuccess(BulkCopySimpleResultSet internal
2698
2712
private void CopyBatchesAsyncContinuedOnError ( bool cleanupParser )
2699
2713
{
2700
2714
SqlInternalConnectionTds internalConnection = _connection . GetOpenTdsConnection ( ) ;
2715
+ #if NETFRAMEWORK
2716
+ RuntimeHelpers . PrepareConstrainedRegions ( ) ;
2717
+ #endif
2701
2718
try
2702
2719
{
2703
2720
if ( ( cleanupParser ) & & ( _parser != null ) && ( _stateObj != null ) )
@@ -2838,7 +2855,8 @@ private void WriteToServerInternalRestContinuedAsync(BulkCopySimpleResultSet int
2838
2855
}
2839
2856
}
2840
2857
}
2841
- }
2858
+ } ,
2859
+ connectionToDoom : _connection . GetOpenTdsConnection ( )
2842
2860
) ;
2843
2861
return ;
2844
2862
}
@@ -2957,6 +2975,7 @@ private void WriteToServerInternalRestAsync(CancellationToken cts, TaskCompletio
2957
2975
_parserLock . Wait ( canReleaseFromAnyThread : true ) ;
2958
2976
WriteToServerInternalRestAsync ( cts , source ) ;
2959
2977
} ,
2978
+ connectionToAbort : _connection ,
2960
2979
onFailure : static ( Exception _ , object state ) => ( ( StrongBox < CancellationTokenRegistration > ) state ) . Value . Dispose ( ) ,
2961
2980
onCancellation : static ( object state ) => ( ( StrongBox < CancellationTokenRegistration > ) state ) . Value . Dispose ( ) ,
2962
2981
exceptionConverter : ( ex ) => SQL . BulkLoadInvalidDestinationTable ( _destinationTableName , ex ) ) ;
@@ -3008,7 +3027,8 @@ private void WriteToServerInternalRestAsync(CancellationToken cts, TaskCompletio
3008
3027
if ( internalResultsTask != null )
3009
3028
{
3010
3029
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 ( )
3012
3032
) ;
3013
3033
}
3014
3034
else
@@ -3092,7 +3112,8 @@ private Task WriteToServerInternalAsync(CancellationToken ctoken)
3092
3112
{
3093
3113
sqlBulkCopy . WriteToServerInternalRestAsync ( ctoken , source ) ; // Passing the same completion which will be completed by the Callee.
3094
3114
}
3095
- }
3115
+ } ,
3116
+ connectionToDoom : _connection . GetOpenTdsConnection ( )
3096
3117
) ;
3097
3118
return resultTask ;
3098
3119
}
0 commit comments