@@ -440,7 +440,23 @@ public async Task StartDownloadsAsync(DownloadDiscoveryResult discoveryResult, E
440440 catch ( Exception ex )
441441 {
442442 _downloadException = ex ;
443- _logger . Error ( ex , "MultipartDownloadManager: Background download task failed" ) ;
443+
444+
445+
446+ // Cancel all remaining downloads immediately to prevent cascading timeout errors
447+ // This ensures that when one part fails, other tasks stop gracefully instead of
448+ // continuing until they hit their own timeout/cancellation errors
449+ try
450+ {
451+ internalCts . Cancel ( ) ;
452+ _logger . DebugFormat ( "MultipartDownloadManager: Cancelled all in-flight downloads due to error" ) ;
453+ }
454+ catch ( ObjectDisposedException )
455+ {
456+ // CancellationTokenSource was already disposed, ignore
457+ _logger . DebugFormat ( "MultipartDownloadManager: CancellationTokenSource already disposed during cancellation" ) ;
458+ }
459+
444460 _dataHandler . OnDownloadComplete ( ex ) ;
445461 throw ;
446462 }
@@ -462,6 +478,18 @@ public async Task StartDownloadsAsync(DownloadDiscoveryResult discoveryResult, E
462478 _downloadException = ex ;
463479 _logger . Error ( ex , "MultipartDownloadManager: Download failed" ) ;
464480
481+ // Cancel all remaining downloads immediately to prevent cascading timeout errors
482+ try
483+ {
484+ internalCts . Cancel ( ) ;
485+ _logger . DebugFormat ( "MultipartDownloadManager: Cancelled all in-flight downloads due to error" ) ;
486+ }
487+ catch ( ObjectDisposedException )
488+ {
489+ // CancellationTokenSource was already disposed, ignore
490+ _logger . DebugFormat ( "MultipartDownloadManager: CancellationTokenSource already disposed during cancellation" ) ;
491+ }
492+
465493 _dataHandler . OnDownloadComplete ( ex ) ;
466494
467495 // Dispose the CancellationTokenSource if background task was never started
0 commit comments