| 
					
				 | 
			
			
				@@ -13,17 +13,13 @@ using MediaBrowser.Model.Entities; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using MediaBrowser.Model.Logging; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using MediaBrowser.Model.Providers; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using System; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-using System.Collections.Concurrent; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using System.Collections.Generic; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using System.IO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using System.Linq; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using System.Threading; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using System.Threading.Tasks; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using MediaBrowser.Model.IO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using MediaBrowser.Controller.Dto; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-using MediaBrowser.Controller.IO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-using MediaBrowser.Model.IO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using MediaBrowser.Model.Serialization; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using Priority_Queue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -69,6 +65,7 @@ namespace MediaBrowser.Providers.Manager 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private readonly Func<ILibraryManager> _libraryManagerFactory; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private readonly IMemoryStreamFactory _memoryStreamProvider; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        private CancellationTokenSource _disposeCancellationTokenSource = new CancellationTokenSource(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /// <summary> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /// Initializes a new instance of the <see cref="ProviderManager" /> class. 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -882,6 +879,13 @@ namespace MediaBrowser.Providers.Manager 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             Tuple<Guid, MetadataRefreshOptions> refreshItem; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             var libraryManager = _libraryManagerFactory(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (_disposed) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var cancellationToken = _disposeCancellationTokenSource.Token; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             while (_refreshQueue.TryDequeue(out refreshItem)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 if (_disposed) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -902,18 +906,22 @@ namespace MediaBrowser.Providers.Manager 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             var folder = item as Folder; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             if (folder != null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                await folder.ValidateChildren(new Progress<double>(), CancellationToken.None).ConfigureAwait(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                await folder.ValidateChildren(new Progress<double>(), cancellationToken).ConfigureAwait(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         var artist = item as MusicArtist; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         var task = artist == null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            ? RefreshItem(item, refreshItem.Item2, CancellationToken.None) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            : RefreshArtist(artist, refreshItem.Item2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            ? RefreshItem(item, refreshItem.Item2, cancellationToken) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            : RefreshArtist(artist, refreshItem.Item2, cancellationToken); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         await task.ConfigureAwait(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                catch (OperationCanceledException) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 catch (Exception ex) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     _logger.ErrorException("Error refreshing item", ex); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -928,14 +936,14 @@ namespace MediaBrowser.Providers.Manager 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private async Task RefreshItem(BaseItem item, MetadataRefreshOptions options, CancellationToken cancellationToken) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            await item.RefreshMetadata(options, CancellationToken.None).ConfigureAwait(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            await item.RefreshMetadata(options, cancellationToken).ConfigureAwait(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             // Collection folders don't validate their children so we'll have to simulate that here 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             var collectionFolder = item as CollectionFolder; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (collectionFolder != null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                await RefreshCollectionFolderChildren(options, collectionFolder).ConfigureAwait(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                await RefreshCollectionFolderChildren(options, collectionFolder, cancellationToken).ConfigureAwait(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -948,25 +956,23 @@ namespace MediaBrowser.Providers.Manager 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        private async Task RefreshCollectionFolderChildren(MetadataRefreshOptions options, CollectionFolder collectionFolder) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        private async Task RefreshCollectionFolderChildren(MetadataRefreshOptions options, CollectionFolder collectionFolder, CancellationToken cancellationToken) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             foreach (var child in collectionFolder.Children.ToList()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                await child.RefreshMetadata(options, CancellationToken.None).ConfigureAwait(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                await child.RefreshMetadata(options, cancellationToken).ConfigureAwait(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 if (child.IsFolder) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     var folder = (Folder)child; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    await folder.ValidateChildren(new Progress<double>(), CancellationToken.None, options, true).ConfigureAwait(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    await folder.ValidateChildren(new Progress<double>(), cancellationToken, options, true).ConfigureAwait(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        private async Task RefreshArtist(MusicArtist item, MetadataRefreshOptions options) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        private async Task RefreshArtist(MusicArtist item, MetadataRefreshOptions options, CancellationToken cancellationToken) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var cancellationToken = CancellationToken.None; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             var albums = _libraryManagerFactory() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 .GetItemList(new InternalItemsQuery 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -991,7 +997,7 @@ namespace MediaBrowser.Providers.Manager 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             try 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                await item.RefreshMetadata(options, CancellationToken.None).ConfigureAwait(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                await item.RefreshMetadata(options, cancellationToken).ConfigureAwait(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             catch (Exception ex) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1009,6 +1015,11 @@ namespace MediaBrowser.Providers.Manager 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         public void Dispose() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             _disposed = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!_disposeCancellationTokenSource.IsCancellationRequested) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                _disposeCancellationTokenSource.Cancel(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |