@@ -678,16 +678,28 @@ await lastFMRealm.WriteAsync(() =>
678678 var duration = endTime - startTime ;
679679 Debug . WriteLine (
680680 $ "{ DateTime . Now } : Finished InitializeAllVMCoreComponentsAsync in { duration . TotalSeconds } seconds.") ;
681+
682+ // Initialize background caching with proper error handling and cancellation support
683+ _backgroundCachingCts = new CancellationTokenSource ( ) ;
681684 _ = Task . Run ( async ( ) =>
682685 {
683- await OnAppOpening ( ) ;
684- await HeavierBackGroundLoadings ( FolderPaths ) ;
686+ try
687+ {
688+ await OnAppOpening ( ) ;
689+ await HeavierBackGroundLoadings ( FolderPaths ) ;
685690
686- await Task . Delay ( 3000 ) ;
687- await EnsureAllCoverArtCachedForSongsAsync ( ) ;
688- CancellationTokenSource cts = new ( ) ;
689- //await LoadAllSongsLyricsFromOnlineAsync(cts);
690- } ) ;
691+ await Task . Delay ( 3000 , _backgroundCachingCts . Token ) ;
692+ await EnsureAllCoverArtCachedForSongsAsync ( _backgroundCachingCts . Token ) ;
693+ }
694+ catch ( OperationCanceledException )
695+ {
696+ _logger . LogInformation ( "Background cover art caching was cancelled." ) ;
697+ }
698+ catch ( Exception ex )
699+ {
700+ _logger . LogError ( ex , "Error during background initialization and cover art caching." ) ;
701+ }
702+ } , _backgroundCachingCts . Token ) ;
691703
692704 IsInitialized = true ;
693705 return ;
@@ -1389,6 +1401,9 @@ public async Task PlayPlaylist(PlaylistModelView? playlist)
13891401 public IDimmerAudioService AudioService => _audioService ;
13901402 private ILibraryScannerService libScannerService ;
13911403
1404+ // Cancellation token for background cover art caching to prevent memory issues on Android
1405+ private CancellationTokenSource ? _backgroundCachingCts ;
1406+
13921407 public CompositeDisposable SubsManager => _subsManager ;
13931408 private readonly CompositeDisposable _subsManager = new CompositeDisposable ( ) ;
13941409
@@ -2334,7 +2349,7 @@ public async Task LoadAndCacheCoverArtAsync(SongModelView song)
23342349 [ ObservableProperty ]
23352350 public partial Progress < ( int current , int total , SongModelView song ) > ProgressCoverArtLoad { get ; set ; }
23362351 [ RelayCommand ]
2337- public async Task EnsureAllCoverArtCachedForSongsAsync ( )
2352+ public async Task EnsureAllCoverArtCachedForSongsAsync ( CancellationToken cancellationToken = default )
23382353 {
23392354 IsAppLoadingCovers = true ;
23402355 // 1. Get the TOTAL count safely using a short-lived Realm instance
@@ -2354,9 +2369,13 @@ public async Task EnsureAllCoverArtCachedForSongsAsync()
23542369
23552370 int processedCount = 0 ;
23562371
2372+ // Use lower parallelism on Android to reduce memory pressure
2373+ var maxParallelism = DeviceInfo . Platform == DevicePlatform . Android ? 4 : 8 ;
2374+
23572375 var parallelOptions = new ParallelOptions
23582376 {
2359- MaxDegreeOfParallelism = 8
2377+ MaxDegreeOfParallelism = maxParallelism ,
2378+ CancellationToken = cancellationToken
23602379 } ;
23612380 var batches = songsToProcessIds . Chunk ( 20 ) ;
23622381
@@ -2377,6 +2396,9 @@ await Parallel.ForEachAsync(batches, parallelOptions, async (batchOfIds, ct) =>
23772396 }
23782397 foreach ( var songView in songsInBatch )
23792398 {
2399+ // Check cancellation before processing each song
2400+ ct . ThrowIfCancellationRequested ( ) ;
2401+
23802402 bool needsProcessing = string . IsNullOrEmpty ( songView . CoverImagePath )
23812403 || ! TaggingUtils . FileExists ( songView . CoverImagePath ) ;
23822404
@@ -5135,6 +5157,11 @@ protected virtual void Dispose(bool disposing)
51355157
51365158 if ( disposing )
51375159 {
5160+ // Cancel background caching operations
5161+ _backgroundCachingCts ? . Cancel ( ) ;
5162+ _backgroundCachingCts ? . Dispose ( ) ;
5163+ _backgroundCachingCts = null ;
5164+
51385165 _realmSubscription ? . Dispose ( ) ;
51395166 _playEventSource . Dispose ( ) ;
51405167 realm ? . Dispose ( ) ;
0 commit comments