Kaynağa Gözat

reduce task allocations by making IBN api synchronous

Luke Pulverenti 11 yıl önce
ebeveyn
işleme
1007f24200
27 değiştirilmiş dosya ile 200 ekleme ve 377 silme
  1. 17 17
      MediaBrowser.Api/BaseApiService.cs
  2. 12 23
      MediaBrowser.Api/DefaultTheme/DefaultThemeService.cs
  3. 9 9
      MediaBrowser.Api/Images/ImageService.cs
  4. 2 2
      MediaBrowser.Api/InstantMixService.cs
  5. 8 8
      MediaBrowser.Api/ItemRefreshService.cs
  6. 7 7
      MediaBrowser.Api/ItemUpdateService.cs
  7. 2 12
      MediaBrowser.Api/UserLibrary/ArtistsService.cs
  8. 2 3
      MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
  9. 2 12
      MediaBrowser.Api/UserLibrary/GameGenresService.cs
  10. 4 14
      MediaBrowser.Api/UserLibrary/GenresService.cs
  11. 2 2
      MediaBrowser.Api/UserLibrary/ItemByNameUserDataService.cs
  12. 3 13
      MediaBrowser.Api/UserLibrary/MusicGenresService.cs
  13. 3 13
      MediaBrowser.Api/UserLibrary/PersonsService.cs
  14. 3 13
      MediaBrowser.Api/UserLibrary/StudiosService.cs
  15. 3 13
      MediaBrowser.Api/UserLibrary/YearsService.cs
  16. 2 1
      MediaBrowser.Controller/Entities/BaseItem.cs
  17. 5 5
      MediaBrowser.Controller/Entities/Folder.cs
  18. 15 22
      MediaBrowser.Controller/Library/ILibraryManager.cs
  19. 38 56
      MediaBrowser.Server.Implementations/Dto/DtoService.cs
  20. 21 100
      MediaBrowser.Server.Implementations/Library/LibraryManager.cs
  21. 10 8
      MediaBrowser.Server.Implementations/Library/LuceneSearchEngine.cs
  22. 7 6
      MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs
  23. 5 5
      MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs
  24. 5 3
      MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs
  25. 5 3
      MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs
  26. 3 4
      MediaBrowser.Server.Implementations/Library/Validators/PeoplePostScanTask.cs
  27. 5 3
      MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs

+ 17 - 17
MediaBrowser.Api/BaseApiService.cs

@@ -95,32 +95,32 @@ namespace MediaBrowser.Api
         private readonly char[] _dashReplaceChars = new[] { '?', '/' };
         private const char SlugChar = '-';
 
-        protected Task<Artist> GetArtist(string name, ILibraryManager libraryManager)
+        protected Artist GetArtist(string name, ILibraryManager libraryManager)
         {
             return libraryManager.GetArtist(DeSlugArtistName(name, libraryManager));
         }
 
-        protected Task<Studio> GetStudio(string name, ILibraryManager libraryManager)
+        protected Studio GetStudio(string name, ILibraryManager libraryManager)
         {
             return libraryManager.GetStudio(DeSlugStudioName(name, libraryManager));
         }
 
-        protected Task<Genre> GetGenre(string name, ILibraryManager libraryManager)
+        protected Genre GetGenre(string name, ILibraryManager libraryManager)
         {
             return libraryManager.GetGenre(DeSlugGenreName(name, libraryManager));
         }
 
-        protected Task<MusicGenre> GetMusicGenre(string name, ILibraryManager libraryManager)
+        protected MusicGenre GetMusicGenre(string name, ILibraryManager libraryManager)
         {
             return libraryManager.GetMusicGenre(DeSlugGenreName(name, libraryManager));
         }
 
-        protected Task<GameGenre> GetGameGenre(string name, ILibraryManager libraryManager)
+        protected GameGenre GetGameGenre(string name, ILibraryManager libraryManager)
         {
             return libraryManager.GetGameGenre(DeSlugGameGenreName(name, libraryManager));
         }
-        
-        protected Task<Person> GetPerson(string name, ILibraryManager libraryManager)
+
+        protected Person GetPerson(string name, ILibraryManager libraryManager)
         {
             return libraryManager.GetPerson(DeSlugPersonName(name, libraryManager));
         }
@@ -137,7 +137,7 @@ namespace MediaBrowser.Api
             {
                 return name;
             }
-            
+
             return libraryManager.RootFolder.RecursiveChildren
                 .OfType<Audio>()
                 .SelectMany(i =>
@@ -203,7 +203,7 @@ namespace MediaBrowser.Api
 
                 }) ?? name;
         }
-        
+
         /// <summary>
         /// Deslugs a studio name by finding the correct entry in the library
         /// </summary>
@@ -257,37 +257,37 @@ namespace MediaBrowser.Api
         /// <param name="libraryManager">The library manager.</param>
         /// <returns>Task{BaseItem}.</returns>
         /// <exception cref="System.ArgumentException"></exception>
-        protected async Task<BaseItem> GetItemByName(string name, string type, ILibraryManager libraryManager)
+        protected BaseItem GetItemByName(string name, string type, ILibraryManager libraryManager)
         {
             BaseItem item;
 
             if (type.IndexOf("Person", StringComparison.OrdinalIgnoreCase) == 0)
             {
-                item = await GetPerson(name, libraryManager).ConfigureAwait(false);
+                item = GetPerson(name, libraryManager);
             }
             else if (type.IndexOf("Artist", StringComparison.OrdinalIgnoreCase) == 0)
             {
-                item = await GetArtist(name, libraryManager).ConfigureAwait(false);
+                item = GetArtist(name, libraryManager);
             }
             else if (type.IndexOf("Genre", StringComparison.OrdinalIgnoreCase) == 0)
             {
-                item = await GetGenre(name, libraryManager).ConfigureAwait(false);
+                item = GetGenre(name, libraryManager);
             }
             else if (type.IndexOf("MusicGenre", StringComparison.OrdinalIgnoreCase) == 0)
             {
-                item = await GetMusicGenre(name, libraryManager).ConfigureAwait(false);
+                item = GetMusicGenre(name, libraryManager);
             }
             else if (type.IndexOf("GameGenre", StringComparison.OrdinalIgnoreCase) == 0)
             {
-                item = await GetGameGenre(name, libraryManager).ConfigureAwait(false);
+                item = GetGameGenre(name, libraryManager);
             }
             else if (type.IndexOf("Studio", StringComparison.OrdinalIgnoreCase) == 0)
             {
-                item = await GetStudio(name, libraryManager).ConfigureAwait(false);
+                item = GetStudio(name, libraryManager);
             }
             else if (type.IndexOf("Year", StringComparison.OrdinalIgnoreCase) == 0)
             {
-                item = await libraryManager.GetYear(int.Parse(name)).ConfigureAwait(false);
+                item = libraryManager.GetYear(int.Parse(name));
             }
             else
             {

+ 12 - 23
MediaBrowser.Api/DefaultTheme/DefaultThemeService.cs

@@ -139,7 +139,7 @@ namespace MediaBrowser.Api.DefaultTheme
                 .Select(i => _dtoService.GetBaseItemDto(i, fields, user));
 
             view.SpotlightItems = await Task.WhenAll(spotlightItemTasks).ConfigureAwait(false);
-            
+
             return view;
         }
 
@@ -205,7 +205,7 @@ namespace MediaBrowser.Api.DefaultTheme
              .Take(3)
              .ToArray();
 
-            view.ActorItems = await GetActors(series).ConfigureAwait(false);
+            view.ActorItems = GetActors(series);
 
             return view;
         }
@@ -218,8 +218,6 @@ namespace MediaBrowser.Api.DefaultTheme
                 .Where(i => i is Movie || i is Trailer || i is BoxSet)
                 .ToList();
 
-            var actorsTask = GetActors(items);
-
             // Exclude trailers from backdrops because they're not always 1080p
             var itemsWithBackdrops = items.Where(i => i.BackdropImagePaths.Count > 0 && !(i is Trailer))
                 .ToList();
@@ -322,7 +320,7 @@ namespace MediaBrowser.Api.DefaultTheme
              .Take(3)
              .ToArray();
 
-            view.PeopleItems = await actorsTask.ConfigureAwait(false);
+            view.PeopleItems = GetActors(items);
 
             return view;
         }
@@ -362,44 +360,35 @@ namespace MediaBrowser.Api.DefaultTheme
             }
         }
 
-        private async Task<ItemStub[]> GetActors(IEnumerable<BaseItem> mediaItems)
+        private ItemStub[] GetActors(IEnumerable<BaseItem> mediaItems)
         {
-            var actorStubs = new List<ItemStub>();
-
             var actors = mediaItems.SelectMany(i => i.People)
                 .Select(i => i.Name)
                 .Distinct(StringComparer.OrdinalIgnoreCase)
                 .OrderBy(i => Guid.NewGuid())
                 .ToList();
 
-            foreach (var actor in actors)
+            return actors.Select(actor =>
             {
-                if (actorStubs.Count >= 3)
-                {
-                    break;
-                }
-
                 try
                 {
-                    var person = await _libraryManager.GetPerson(actor).ConfigureAwait(false);
+                    var person = _libraryManager.GetPerson(actor);
 
                     if (!string.IsNullOrEmpty(person.PrimaryImagePath))
                     {
-                        var stub = GetItemStub(person, ImageType.Primary);
-
-                        if (stub != null)
-                        {
-                            actorStubs.Add(stub);
-                        }
+                        return GetItemStub(person, ImageType.Primary);
                     }
                 }
                 catch (Exception ex)
                 {
                     _logger.ErrorException("Error getting person {0}", ex, actor);
                 }
-            }
 
-            return actorStubs.ToArray();
+                return null;
+            })
+            .Where(i => i != null)
+            .Take(3)
+            .ToArray();
         }
 
         private ItemStub GetItemStub(BaseItem item, ImageType imageType)

+ 9 - 9
MediaBrowser.Api/Images/ImageService.cs

@@ -140,7 +140,7 @@ namespace MediaBrowser.Api.Images
         [ApiMember(Name = "NewIndex", Description = "The new image index", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
         public int NewIndex { get; set; }
     }
-    
+
     /// <summary>
     /// Class GetPersonImage
     /// </summary>
@@ -378,14 +378,14 @@ namespace MediaBrowser.Api.Images
         /// </summary>
         /// <param name="request">The request.</param>
         /// <returns>Task{List{ImageInfo}}.</returns>
-        public async Task<List<ImageInfo>> GetItemByNameImageInfos(GetItemByNameImageInfos request)
+        public Task<List<ImageInfo>> GetItemByNameImageInfos(GetItemByNameImageInfos request)
         {
             var pathInfo = PathInfo.Parse(RequestContext.PathInfo);
             var type = pathInfo.GetArgumentValue<string>(0);
 
-            var item = await GetItemByName(request.Name, type, _libraryManager).ConfigureAwait(false);
+            var item = GetItemByName(request.Name, type, _libraryManager);
 
-            return await GetItemImageInfos(item).ConfigureAwait(false);
+            return GetItemImageInfos(item);
         }
 
         /// <summary>
@@ -532,7 +532,7 @@ namespace MediaBrowser.Api.Images
             var pathInfo = PathInfo.Parse(RequestContext.PathInfo);
             var type = pathInfo.GetArgumentValue<string>(0);
 
-            var item = GetItemByName(request.Name, type, _libraryManager).Result;
+            var item = GetItemByName(request.Name, type, _libraryManager);
 
             return GetImage(request, item);
         }
@@ -563,13 +563,13 @@ namespace MediaBrowser.Api.Images
 
             request.Type = (ImageType)Enum.Parse(typeof(ImageType), pathInfo.GetArgumentValue<string>(3), true);
 
-            var item = GetItemByName(name, type, _libraryManager).Result;
+            var item = GetItemByName(name, type, _libraryManager);
 
             var task = PostImage(item, request.RequestStream, request.Type, RequestContext.ContentType);
 
             Task.WaitAll(task);
         }
-        
+
         /// <summary>
         /// Posts the specified request.
         /// </summary>
@@ -623,7 +623,7 @@ namespace MediaBrowser.Api.Images
             var pathInfo = PathInfo.Parse(RequestContext.PathInfo);
             var type = pathInfo.GetArgumentValue<string>(0);
 
-            var item = GetItemByName(request.Name, type, _libraryManager).Result;
+            var item = GetItemByName(request.Name, type, _libraryManager);
 
             var task = item.DeleteImage(request.Type, request.Index);
 
@@ -652,7 +652,7 @@ namespace MediaBrowser.Api.Images
             var pathInfo = PathInfo.Parse(RequestContext.PathInfo);
             var type = pathInfo.GetArgumentValue<string>(0);
 
-            var item = GetItemByName(request.Name, type, _libraryManager).Result;
+            var item = GetItemByName(request.Name, type, _libraryManager);
 
             var task = UpdateItemIndex(item, request.Type, request.Index, request.NewIndex);
 

+ 2 - 2
MediaBrowser.Api/InstantMixService.cs

@@ -79,7 +79,7 @@ namespace MediaBrowser.Api
 
         public object Get(GetInstantMixFromMusicGenre request)
         {
-            var genre = GetMusicGenre(request.Name, _libraryManager).Result;
+            var genre = GetMusicGenre(request.Name, _libraryManager);
 
             var result = GetInstantMixResult(request, new[] { genre.Name }).Result;
 
@@ -88,7 +88,7 @@ namespace MediaBrowser.Api
 
         public object Get(GetInstantMixFromArtist request)
         {
-            var artist = GetArtist(request.Name, _libraryManager).Result;
+            var artist = GetArtist(request.Name, _libraryManager);
 
             var genres = _libraryManager.RootFolder
                 .RecursiveChildren

+ 8 - 8
MediaBrowser.Api/ItemRefreshService.cs

@@ -89,7 +89,7 @@ namespace MediaBrowser.Api
         [ApiMember(Name = "Name", Description = "Name", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
         public string Name { get; set; }
     }
-    
+
     public class ItemRefreshService : BaseApiService
     {
         private readonly ILibraryManager _libraryManager;
@@ -110,7 +110,7 @@ namespace MediaBrowser.Api
 
         private async Task RefreshArtist(RefreshArtist request)
         {
-            var item = await GetArtist(request.Name, _libraryManager).ConfigureAwait(false);
+            var item = GetArtist(request.Name, _libraryManager);
 
             var cancellationToken = CancellationToken.None;
 
@@ -148,7 +148,7 @@ namespace MediaBrowser.Api
 
         private async Task RefreshGenre(RefreshGenre request)
         {
-            var item = await GetGenre(request.Name, _libraryManager).ConfigureAwait(false);
+            var item = GetGenre(request.Name, _libraryManager);
 
             try
             {
@@ -169,7 +169,7 @@ namespace MediaBrowser.Api
 
         private async Task RefreshMusicGenre(RefreshMusicGenre request)
         {
-            var item = await GetMusicGenre(request.Name, _libraryManager).ConfigureAwait(false);
+            var item = GetMusicGenre(request.Name, _libraryManager);
 
             try
             {
@@ -190,7 +190,7 @@ namespace MediaBrowser.Api
 
         private async Task RefreshGameGenre(RefreshGameGenre request)
         {
-            var item = await GetGameGenre(request.Name, _libraryManager).ConfigureAwait(false);
+            var item = GetGameGenre(request.Name, _libraryManager);
 
             try
             {
@@ -211,7 +211,7 @@ namespace MediaBrowser.Api
 
         private async Task RefreshPerson(RefreshPerson request)
         {
-            var item = await GetPerson(request.Name, _libraryManager).ConfigureAwait(false);
+            var item = GetPerson(request.Name, _libraryManager);
 
             try
             {
@@ -232,7 +232,7 @@ namespace MediaBrowser.Api
 
         private async Task RefreshStudio(RefreshStudio request)
         {
-            var item = await GetStudio(request.Name, _libraryManager).ConfigureAwait(false);
+            var item = GetStudio(request.Name, _libraryManager);
 
             try
             {
@@ -254,7 +254,7 @@ namespace MediaBrowser.Api
 
             Task.WaitAll(task);
         }
-        
+
         /// <summary>
         /// Refreshes the item.
         /// </summary>

+ 7 - 7
MediaBrowser.Api/ItemUpdateService.cs

@@ -105,7 +105,7 @@ namespace MediaBrowser.Api
 
         private async Task UpdateItem(UpdatePerson request)
         {
-            var item = await GetPerson(request.PersonName, _libraryManager).ConfigureAwait(false);
+            var item = GetPerson(request.PersonName, _libraryManager);
 
             UpdateItem(request, item);
 
@@ -121,7 +121,7 @@ namespace MediaBrowser.Api
 
         private async Task UpdateItem(UpdateArtist request)
         {
-            var item = await GetArtist(request.ArtistName, _libraryManager).ConfigureAwait(false);
+            var item = GetArtist(request.ArtistName, _libraryManager);
 
             UpdateItem(request, item);
 
@@ -137,7 +137,7 @@ namespace MediaBrowser.Api
 
         private async Task UpdateItem(UpdateStudio request)
         {
-            var item = await GetStudio(request.StudioName, _libraryManager).ConfigureAwait(false);
+            var item = GetStudio(request.StudioName, _libraryManager);
 
             UpdateItem(request, item);
 
@@ -153,7 +153,7 @@ namespace MediaBrowser.Api
 
         private async Task UpdateItem(UpdateMusicGenre request)
         {
-            var item = await GetMusicGenre(request.GenreName, _libraryManager).ConfigureAwait(false);
+            var item = GetMusicGenre(request.GenreName, _libraryManager);
 
             UpdateItem(request, item);
 
@@ -169,7 +169,7 @@ namespace MediaBrowser.Api
 
         private async Task UpdateItem(UpdateGameGenre request)
         {
-            var item = await GetGameGenre(request.GenreName, _libraryManager).ConfigureAwait(false);
+            var item = GetGameGenre(request.GenreName, _libraryManager);
 
             UpdateItem(request, item);
 
@@ -185,7 +185,7 @@ namespace MediaBrowser.Api
 
         private async Task UpdateItem(UpdateGenre request)
         {
-            var item = await GetGenre(request.GenreName, _libraryManager).ConfigureAwait(false);
+            var item = GetGenre(request.GenreName, _libraryManager);
 
             UpdateItem(request, item);
 
@@ -212,7 +212,7 @@ namespace MediaBrowser.Api
 
             item.CriticRating = request.CriticRating;
             item.CriticRatingSummary = request.CriticRatingSummary;
-            
+
             item.DisplayMediaType = request.DisplayMediaType;
             item.CommunityRating = request.CommunityRating;
             item.HomePageUrl = request.HomePageUrl;

+ 2 - 12
MediaBrowser.Api/UserLibrary/ArtistsService.cs

@@ -77,7 +77,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <returns>Task{BaseItemDto}.</returns>
         private async Task<BaseItemDto> GetItem(GetArtist request)
         {
-            var item = await GetArtist(request.Name, LibraryManager).ConfigureAwait(false);
+            var item = GetArtist(request.Name, LibraryManager);
 
             // Get everything
             var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true));
@@ -110,7 +110,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <param name="request">The request.</param>
         /// <param name="items">The items.</param>
         /// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
-        protected override IEnumerable<Task<Artist>> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items)
+        protected override IEnumerable<Artist> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items)
         {
             var itemsList = items.OfType<Audio>().ToList();
 
@@ -130,15 +130,5 @@ namespace MediaBrowser.Api.UserLibrary
                 .Distinct(StringComparer.OrdinalIgnoreCase)
                 .Select(name => LibraryManager.GetArtist(name));
         }
-
-        /// <summary>
-        /// Gets the entity.
-        /// </summary>
-        /// <param name="name">The name.</param>
-        /// <returns>Task{Artist}.</returns>
-        protected Task<Artist> GetEntity(string name)
-        {
-            return LibraryManager.GetArtist(name);
-        }
     }
 }

+ 2 - 3
MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs

@@ -90,8 +90,7 @@ namespace MediaBrowser.Api.UserLibrary
 
             items = FilterItems(request, items);
 
-            var ibnItemTasks = GetAllItems(request, items);
-            var extractedItems = await Task.WhenAll(ibnItemTasks).ConfigureAwait(false);
+            var extractedItems = GetAllItems(request, items);
 
             var filteredItems = FilterItems(request, extractedItems, user);
 
@@ -245,7 +244,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <param name="request">The request.</param>
         /// <param name="items">The items.</param>
         /// <returns>IEnumerable{Task{`0}}.</returns>
-        protected abstract IEnumerable<Task<TItemType>> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items);
+        protected abstract IEnumerable<TItemType> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items);
 
         /// <summary>
         /// Gets the dto.

+ 2 - 12
MediaBrowser.Api/UserLibrary/GameGenresService.cs

@@ -68,7 +68,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <returns>Task{BaseItemDto}.</returns>
         private async Task<BaseItemDto> GetItem(GetGameGenre request)
         {
-            var item = await GetGameGenre(request.Name, LibraryManager).ConfigureAwait(false);
+            var item = GetGameGenre(request.Name, LibraryManager);
 
             // Get everything
             var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true));
@@ -101,7 +101,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <param name="request">The request.</param>
         /// <param name="items">The items.</param>
         /// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
-        protected override IEnumerable<Task<GameGenre>> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items)
+        protected override IEnumerable<GameGenre> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items)
         {
             var itemsList = items.Where(i => i.Genres != null).ToList();
 
@@ -110,15 +110,5 @@ namespace MediaBrowser.Api.UserLibrary
                 .Distinct(StringComparer.OrdinalIgnoreCase)
                 .Select(name => LibraryManager.GetGameGenre(name));
         }
-
-        /// <summary>
-        /// Gets the entity.
-        /// </summary>
-        /// <param name="name">The name.</param>
-        /// <returns>Task{Genre}.</returns>
-        protected Task<GameGenre> GetEntity(string name)
-        {
-            return LibraryManager.GetGameGenre(name);
-        }
     }
 }

+ 4 - 14
MediaBrowser.Api/UserLibrary/GenresService.cs

@@ -42,7 +42,7 @@ namespace MediaBrowser.Api.UserLibrary
         [ApiMember(Name = "UserId", Description = "Optional. Filter by user id, and attach user data", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
         public Guid? UserId { get; set; }
     }
-    
+
     /// <summary>
     /// Class GenresService
     /// </summary>
@@ -72,7 +72,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <returns>Task{BaseItemDto}.</returns>
         private async Task<BaseItemDto> GetItem(GetGenre request)
         {
-            var item = await GetGenre(request.Name, LibraryManager).ConfigureAwait(false);
+            var item = GetGenre(request.Name, LibraryManager);
 
             // Get everything
             var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true));
@@ -86,7 +86,7 @@ namespace MediaBrowser.Api.UserLibrary
 
             return await DtoService.GetBaseItemDto(item, fields.ToList()).ConfigureAwait(false);
         }
-       
+
         /// <summary>
         /// Gets the specified request.
         /// </summary>
@@ -105,7 +105,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <param name="request">The request.</param>
         /// <param name="items">The items.</param>
         /// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
-        protected override IEnumerable<Task<Genre>> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items)
+        protected override IEnumerable<Genre> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items)
         {
             var itemsList = items.Where(i => i.Genres != null).ToList();
 
@@ -114,15 +114,5 @@ namespace MediaBrowser.Api.UserLibrary
                 .Distinct(StringComparer.OrdinalIgnoreCase)
                 .Select(name => LibraryManager.GetGenre(name));
         }
-
-        /// <summary>
-        /// Gets the entity.
-        /// </summary>
-        /// <param name="name">The name.</param>
-        /// <returns>Task{Genre}.</returns>
-        protected Task<Genre> GetEntity(string name)
-        {
-            return LibraryManager.GetGenre(name);
-        }
     }
 }

+ 2 - 2
MediaBrowser.Api/UserLibrary/ItemByNameUserDataService.cs

@@ -218,7 +218,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <returns>Task.</returns>
         protected async Task<UserItemDataDto> MarkFavorite(Guid userId, string type, string name, bool isFavorite)
         {
-            var item = await GetItemByName(name, type, LibraryManager).ConfigureAwait(false);
+            var item = GetItemByName(name, type, LibraryManager);
 
             var key = item.GetUserDataKey();
 
@@ -245,7 +245,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <returns>Task.</returns>
         protected async Task<UserItemDataDto> MarkLike(Guid userId, string type, string name, bool? likes)
         {
-            var item = await GetItemByName(name, type, LibraryManager).ConfigureAwait(false);
+            var item = GetItemByName(name, type, LibraryManager);
 
             var key = item.GetUserDataKey();
 

+ 3 - 13
MediaBrowser.Api/UserLibrary/MusicGenresService.cs

@@ -19,7 +19,7 @@ namespace MediaBrowser.Api.UserLibrary
     {
         public GetMusicGenres()
         {
-            IncludeItemTypes = typeof (Audio).Name;
+            IncludeItemTypes = typeof(Audio).Name;
         }
     }
 
@@ -68,7 +68,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <returns>Task{BaseItemDto}.</returns>
         private async Task<BaseItemDto> GetItem(GetMusicGenre request)
         {
-            var item = await GetMusicGenre(request.Name, LibraryManager).ConfigureAwait(false);
+            var item = GetMusicGenre(request.Name, LibraryManager);
 
             // Get everything
             var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true));
@@ -101,7 +101,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <param name="request">The request.</param>
         /// <param name="items">The items.</param>
         /// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
-        protected override IEnumerable<Task<MusicGenre>> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items)
+        protected override IEnumerable<MusicGenre> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items)
         {
             var itemsList = items.ToList();
 
@@ -110,15 +110,5 @@ namespace MediaBrowser.Api.UserLibrary
                 .Distinct(StringComparer.OrdinalIgnoreCase)
                 .Select(name => LibraryManager.GetMusicGenre(name));
         }
-
-        /// <summary>
-        /// Gets the entity.
-        /// </summary>
-        /// <param name="name">The name.</param>
-        /// <returns>Task{Genre}.</returns>
-        protected Task<MusicGenre> GetEntity(string name)
-        {
-            return LibraryManager.GetMusicGenre(name);
-        }
     }
 }

+ 3 - 13
MediaBrowser.Api/UserLibrary/PersonsService.cs

@@ -84,11 +84,11 @@ namespace MediaBrowser.Api.UserLibrary
         /// <returns>Task{BaseItemDto}.</returns>
         private async Task<BaseItemDto> GetItem(GetPerson request)
         {
-            var item = await GetPerson(request.Name, LibraryManager).ConfigureAwait(false);
+            var item = GetPerson(request.Name, LibraryManager);
 
             // Get everything
             var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true));
-            
+
             if (request.UserId.HasValue)
             {
                 var user = UserManager.GetUserById(request.UserId.Value);
@@ -117,7 +117,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <param name="request">The request.</param>
         /// <param name="items">The items.</param>
         /// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
-        protected override IEnumerable<Task<Person>> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items)
+        protected override IEnumerable<Person> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items)
         {
             var inputPersonTypes = ((GetPersons)request).PersonTypes;
             var personTypes = string.IsNullOrEmpty(inputPersonTypes) ? new string[] { } : inputPersonTypes.Split(',');
@@ -151,15 +151,5 @@ namespace MediaBrowser.Api.UserLibrary
 
                 people.Where(p => personTypes.Contains(p.Type ?? string.Empty, StringComparer.OrdinalIgnoreCase) || personTypes.Contains(p.Role ?? string.Empty, StringComparer.OrdinalIgnoreCase));
         }
-
-        /// <summary>
-        /// Gets the entity.
-        /// </summary>
-        /// <param name="name">The name.</param>
-        /// <returns>Task{Genre}.</returns>
-        protected Task<Person> GetEntity(string name)
-        {
-            return LibraryManager.GetPerson(name);
-        }
     }
 }

+ 3 - 13
MediaBrowser.Api/UserLibrary/StudiosService.cs

@@ -72,11 +72,11 @@ namespace MediaBrowser.Api.UserLibrary
         /// <returns>Task{BaseItemDto}.</returns>
         private async Task<BaseItemDto> GetItem(GetStudio request)
         {
-            var item = await GetStudio(request.Name, LibraryManager).ConfigureAwait(false);
+            var item = GetStudio(request.Name, LibraryManager);
 
             // Get everything
             var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true));
-            
+
             if (request.UserId.HasValue)
             {
                 var user = UserManager.GetUserById(request.UserId.Value);
@@ -105,7 +105,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <param name="request">The request.</param>
         /// <param name="items">The items.</param>
         /// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
-        protected override IEnumerable<Task<Studio>> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items)
+        protected override IEnumerable<Studio> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items)
         {
             var itemsList = items.Where(i => i.Studios != null).ToList();
 
@@ -114,15 +114,5 @@ namespace MediaBrowser.Api.UserLibrary
                 .Distinct(StringComparer.OrdinalIgnoreCase)
                 .Select(name => LibraryManager.GetStudio(name));
         }
-
-        /// <summary>
-        /// Gets the entity.
-        /// </summary>
-        /// <param name="name">The name.</param>
-        /// <returns>Task{Studio}.</returns>
-        protected Task<Studio> GetEntity(string name)
-        {
-            return LibraryManager.GetStudio(name);
-        }
     }
 }

+ 3 - 13
MediaBrowser.Api/UserLibrary/YearsService.cs

@@ -78,11 +78,11 @@ namespace MediaBrowser.Api.UserLibrary
         /// <returns>Task{BaseItemDto}.</returns>
         private async Task<BaseItemDto> GetItem(GetYear request)
         {
-            var item = await LibraryManager.GetYear(request.Year).ConfigureAwait(false);
+            var item = LibraryManager.GetYear(request.Year);
 
             // Get everything
             var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true));
-            
+
             if (request.UserId.HasValue)
             {
                 var user = UserManager.GetUserById(request.UserId.Value);
@@ -111,7 +111,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <param name="request">The request.</param>
         /// <param name="items">The items.</param>
         /// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
-        protected override IEnumerable<Task<Year>> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items)
+        protected override IEnumerable<Year> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items)
         {
             var itemsList = items.Where(i => i.ProductionYear != null).ToList();
 
@@ -120,15 +120,5 @@ namespace MediaBrowser.Api.UserLibrary
                 .Distinct()
                 .Select(year => LibraryManager.GetYear(year));
         }
-
-        /// <summary>
-        /// Gets the entity.
-        /// </summary>
-        /// <param name="name">The name.</param>
-        /// <returns>Task{Studio}.</returns>
-        protected Task<Year> GetEntity(string name)
-        {
-            return LibraryManager.GetYear(int.Parse(name, UsCulture));
-        }
     }
 }

+ 2 - 1
MediaBrowser.Controller/Entities/BaseItem.cs

@@ -1,4 +1,5 @@
-using MediaBrowser.Common.Extensions;
+using System.Runtime.InteropServices;
+using MediaBrowser.Common.Extensions;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.IO;
 using MediaBrowser.Controller.Library;

+ 5 - 5
MediaBrowser.Controller/Entities/Folder.cs

@@ -235,7 +235,7 @@ namespace MediaBrowser.Controller.Entities
                     {
                         try
                         {
-                            return LibraryManager.GetPerson(i).Result;
+                            return LibraryManager.GetPerson(i);
                         }
                         catch (IOException ex)
                         {
@@ -263,7 +263,7 @@ namespace MediaBrowser.Controller.Entities
                     {
                         try
                         {
-                            return LibraryManager.GetArtist(i).Result;
+                            return LibraryManager.GetArtist(i);
                         }
                         catch (IOException ex)
                         {
@@ -307,7 +307,7 @@ namespace MediaBrowser.Controller.Entities
                     {
                         try
                         {
-                            return LibraryManager.GetStudio(i).Result;
+                            return LibraryManager.GetStudio(i);
                         }
                         catch (IOException ex)
                         {
@@ -347,7 +347,7 @@ namespace MediaBrowser.Controller.Entities
                         {
                             try
                             {
-                                return LibraryManager.GetGenre(i).Result;
+                                return LibraryManager.GetGenre(i);
                             }
                             catch (Exception ex)
                             {
@@ -383,7 +383,7 @@ namespace MediaBrowser.Controller.Entities
                     {
                         try
                         {
-                            return LibraryManager.GetYear(i).Result;
+                            return LibraryManager.GetYear(i);
                         }
                         catch (IOException ex)
                         {

+ 15 - 22
MediaBrowser.Controller/Library/ILibraryManager.cs

@@ -39,7 +39,7 @@ namespace MediaBrowser.Controller.Library
         /// <param name="files">The files.</param>
         /// <param name="parent">The parent.</param>
         /// <returns>List{``0}.</returns>
-        List<T> ResolvePaths<T>(IEnumerable<FileSystemInfo> files, Folder parent) 
+        List<T> ResolvePaths<T>(IEnumerable<FileSystemInfo> files, Folder parent)
             where T : BaseItem;
 
         /// <summary>
@@ -54,58 +54,51 @@ namespace MediaBrowser.Controller.Library
         /// Gets a Person
         /// </summary>
         /// <param name="name">The name.</param>
-        /// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
         /// <returns>Task{Person}.</returns>
-        Task<Person> GetPerson(string name, bool allowSlowProviders = false);
+        Person GetPerson(string name);
 
         /// <summary>
         /// Gets the artist.
         /// </summary>
         /// <param name="name">The name.</param>
-        /// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
         /// <returns>Task{Artist}.</returns>
-        Task<Artist> GetArtist(string name, bool allowSlowProviders = false);
+        Artist GetArtist(string name);
 
         /// <summary>
         /// Gets a Studio
         /// </summary>
         /// <param name="name">The name.</param>
-        /// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
         /// <returns>Task{Studio}.</returns>
-        Task<Studio> GetStudio(string name, bool allowSlowProviders = false);
+        Studio GetStudio(string name);
 
         /// <summary>
         /// Gets a Genre
         /// </summary>
         /// <param name="name">The name.</param>
-        /// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
         /// <returns>Task{Genre}.</returns>
-        Task<Genre> GetGenre(string name, bool allowSlowProviders = false);
+        Genre GetGenre(string name);
 
         /// <summary>
         /// Gets the genre.
         /// </summary>
         /// <param name="name">The name.</param>
-        /// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
         /// <returns>Task{MusicGenre}.</returns>
-        Task<MusicGenre> GetMusicGenre(string name, bool allowSlowProviders = false);
+        MusicGenre GetMusicGenre(string name);
 
         /// <summary>
         /// Gets the game genre.
         /// </summary>
         /// <param name="name">The name.</param>
-        /// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
         /// <returns>Task{GameGenre}.</returns>
-        Task<GameGenre> GetGameGenre(string name, bool allowSlowProviders = false);
-        
+        GameGenre GetGameGenre(string name);
+
         /// <summary>
         /// Gets a Year
         /// </summary>
         /// <param name="value">The value.</param>
-        /// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
         /// <returns>Task{Year}.</returns>
         /// <exception cref="System.ArgumentOutOfRangeException"></exception>
-        Task<Year> GetYear(int value, bool allowSlowProviders = false);
+        Year GetYear(int value);
 
         /// <summary>
         /// Validate and refresh the People sub-set of the IBN.
@@ -163,10 +156,10 @@ namespace MediaBrowser.Controller.Library
         /// <param name="prescanTasks">The prescan tasks.</param>
         /// <param name="postscanTasks">The postscan tasks.</param>
         /// <param name="savers">The savers.</param>
-        void AddParts(IEnumerable<IResolverIgnoreRule> rules, 
-            IEnumerable<IVirtualFolderCreator> pluginFolders, 
-            IEnumerable<IItemResolver> resolvers, 
-            IEnumerable<IIntroProvider> introProviders, 
+        void AddParts(IEnumerable<IResolverIgnoreRule> rules,
+            IEnumerable<IVirtualFolderCreator> pluginFolders,
+            IEnumerable<IItemResolver> resolvers,
+            IEnumerable<IIntroProvider> introProviders,
             IEnumerable<IBaseItemComparer> itemComparers,
             IEnumerable<ILibraryPrescanTask> prescanTasks,
             IEnumerable<ILibraryPostScanTask> postscanTasks,
@@ -260,7 +253,7 @@ namespace MediaBrowser.Controller.Library
         /// <param name="progress">The progress.</param>
         /// <returns>Task.</returns>
         Task ValidateGenres(CancellationToken cancellationToken, IProgress<double> progress);
-        
+
         /// <summary>
         /// Validates the studios.
         /// </summary>
@@ -268,7 +261,7 @@ namespace MediaBrowser.Controller.Library
         /// <param name="progress">The progress.</param>
         /// <returns>Task.</returns>
         Task ValidateStudios(CancellationToken cancellationToken, IProgress<double> progress);
-        
+
         /// <summary>
         /// Occurs when [item added].
         /// </summary>

+ 38 - 56
MediaBrowser.Server.Implementations/Dto/DtoService.cs

@@ -38,8 +38,8 @@ namespace MediaBrowser.Server.Implementations.Dto
             _userManager = userManager;
             _userDataRepository = userDataRepository;
             _itemRepo = itemRepo;
-        }        
-        
+        }
+
         /// <summary>
         /// Converts a BaseItem to a DTOBaseItem
         /// </summary>
@@ -63,16 +63,9 @@ namespace MediaBrowser.Server.Implementations.Dto
 
             var dto = new BaseItemDto();
 
-            var tasks = new List<Task>();
-
-            if (fields.Contains(ItemFields.Studios))
-            {
-                tasks.Add(AttachStudios(dto, item));
-            }
-
             if (fields.Contains(ItemFields.People))
             {
-                tasks.Add(AttachPeople(dto, item));
+                AttachPeople(dto, item);
             }
 
             if (fields.Contains(ItemFields.PrimaryImageAspectRatio))
@@ -98,6 +91,11 @@ namespace MediaBrowser.Server.Implementations.Dto
                 AttachUserSpecificInfo(dto, item, user, fields);
             }
 
+            if (fields.Contains(ItemFields.Studios))
+            {
+                AttachStudios(dto, item);
+            }
+
             AttachBasicFields(dto, item, owner, fields);
 
             if (fields.Contains(ItemFields.SoundtrackIds))
@@ -116,12 +114,6 @@ namespace MediaBrowser.Server.Implementations.Dto
                 }
             }
 
-            // Make sure all the tasks we kicked off have completed.
-            if (tasks.Count > 0)
-            {
-                await Task.WhenAll(tasks).ConfigureAwait(false);
-            }
-
             return dto;
         }
 
@@ -425,15 +417,15 @@ namespace MediaBrowser.Server.Implementations.Dto
                 _logger.ErrorException("Error getting {0} image info for {1}", ex, type, path);
                 return null;
             }
-        }        
-        
+        }
+
         /// <summary>
         /// Attaches People DTO's to a DTOBaseItem
         /// </summary>
         /// <param name="dto">The dto.</param>
         /// <param name="item">The item.</param>
         /// <returns>Task.</returns>
-        private async Task AttachPeople(BaseItemDto dto, BaseItem item)
+        private void AttachPeople(BaseItemDto dto, BaseItem item)
         {
             // Ordering by person type to ensure actors and artists are at the front.
             // This is taking advantage of the fact that they both begin with A
@@ -443,24 +435,20 @@ namespace MediaBrowser.Server.Implementations.Dto
             // Attach People by transforming them into BaseItemPerson (DTO)
             dto.People = new BaseItemPerson[people.Count];
 
-            var entities = await Task.WhenAll(people.Select(p => p.Name)
+            var dictionary = people.Select(p => p.Name)
                 .Distinct(StringComparer.OrdinalIgnoreCase).Select(c =>
-                    Task.Run(async () =>
+                {
+                    try
+                    {
+                        return _libraryManager.GetPerson(c);
+                    }
+                    catch (IOException ex)
                     {
-                        try
-                        {
-                            return await _libraryManager.GetPerson(c).ConfigureAwait(false);
-                        }
-                        catch (IOException ex)
-                        {
-                            _logger.ErrorException("Error getting person {0}", ex, c);
-                            return null;
-                        }
-                    })
-
-            )).ConfigureAwait(false);
-
-            var dictionary = entities.Where(i => i != null)
+                        _logger.ErrorException("Error getting person {0}", ex, c);
+                        return null;
+                    }
+
+                }).Where(i => i != null)
                 .DistinctBy(i => i.Name)
                 .ToDictionary(i => i.Name, StringComparer.OrdinalIgnoreCase);
 
@@ -497,32 +485,26 @@ namespace MediaBrowser.Server.Implementations.Dto
         /// <param name="dto">The dto.</param>
         /// <param name="item">The item.</param>
         /// <returns>Task.</returns>
-        private async Task AttachStudios(BaseItemDto dto, BaseItem item)
+        private void AttachStudios(BaseItemDto dto, BaseItem item)
         {
             var studios = item.Studios.ToList();
 
             dto.Studios = new StudioDto[studios.Count];
 
-            var entities = await Task.WhenAll(studios.Distinct(StringComparer.OrdinalIgnoreCase).Select(c =>
-
-                    Task.Run(async () =>
-                    {
-                        try
-                        {
-                            return await _libraryManager.GetStudio(c).ConfigureAwait(false);
-                        }
-                        catch (IOException ex)
-                        {
-                            _logger.ErrorException("Error getting studio {0}", ex, c);
-                            return null;
-                        }
-                    })
-
-            )).ConfigureAwait(false);
-
-            var dictionary = entities
-                .Where(i => i != null)
-                .ToDictionary(i => i.Name, StringComparer.OrdinalIgnoreCase);
+            var dictionary = studios.Distinct(StringComparer.OrdinalIgnoreCase).Select(name =>
+            {
+                try
+                {
+                    return _libraryManager.GetStudio(name);
+                }
+                catch (IOException ex)
+                {
+                    _logger.ErrorException("Error getting studio {0}", ex, name);
+                    return null;
+                }
+            })
+            .Where(i => i != null)
+            .ToDictionary(i => i.Name, StringComparer.OrdinalIgnoreCase);
 
             for (var i = 0; i < studios.Count; i++)
             {

+ 21 - 100
MediaBrowser.Server.Implementations/Library/LibraryManager.cs

@@ -590,144 +590,60 @@ namespace MediaBrowser.Server.Implementations.Library
         /// Gets a Person
         /// </summary>
         /// <param name="name">The name.</param>
-        /// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
-        /// <returns>Task{Person}.</returns>
-        public Task<Person> GetPerson(string name, bool allowSlowProviders = false)
-        {
-            return GetPerson(name, CancellationToken.None, allowSlowProviders);
-        }
-
-        /// <summary>
-        /// Gets a Person
-        /// </summary>
-        /// <param name="name">The name.</param>
-        /// <param name="cancellationToken">The cancellation token.</param>
-        /// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
-        /// <param name="refreshMetadata">if set to <c>true</c> [force creation].</param>
         /// <returns>Task{Person}.</returns>
-        private Task<Person> GetPerson(string name, CancellationToken cancellationToken, bool allowSlowProviders = false, bool refreshMetadata = false)
+        public Person GetPerson(string name)
         {
-            return GetItemByName<Person>(ConfigurationManager.ApplicationPaths.PeoplePath, name, cancellationToken, allowSlowProviders, refreshMetadata);
+            return GetItemByName<Person>(ConfigurationManager.ApplicationPaths.PeoplePath, name);
         }
 
         /// <summary>
         /// Gets a Studio
         /// </summary>
         /// <param name="name">The name.</param>
-        /// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
-        /// <returns>Task{Studio}.</returns>
-        public Task<Studio> GetStudio(string name, bool allowSlowProviders = false)
-        {
-            return GetStudio(name, CancellationToken.None, allowSlowProviders);
-        }
-
-        /// <summary>
-        /// Gets the studio.
-        /// </summary>
-        /// <param name="name">The name.</param>
-        /// <param name="cancellationToken">The cancellation token.</param>
-        /// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
-        /// <param name="refreshMetadata">if set to <c>true</c> [refresh metadata].</param>
         /// <returns>Task{Studio}.</returns>
-        internal Task<Studio> GetStudio(string name, CancellationToken cancellationToken, bool allowSlowProviders = false, bool refreshMetadata = false)
+        public Studio GetStudio(string name)
         {
-            return GetItemByName<Studio>(ConfigurationManager.ApplicationPaths.StudioPath, name, cancellationToken, allowSlowProviders, refreshMetadata);
+            return GetItemByName<Studio>(ConfigurationManager.ApplicationPaths.StudioPath, name);
         }
 
         /// <summary>
         /// Gets a Genre
         /// </summary>
         /// <param name="name">The name.</param>
-        /// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
-        /// <returns>Task{Genre}.</returns>
-        public Task<Genre> GetGenre(string name, bool allowSlowProviders = false)
-        {
-            return GetGenre(name, CancellationToken.None, allowSlowProviders);
-        }
-
-        /// <summary>
-        /// Gets the genre.
-        /// </summary>
-        /// <param name="name">The name.</param>
-        /// <param name="cancellationToken">The cancellation token.</param>
-        /// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
-        /// <param name="refreshMetadata">if set to <c>true</c> [refresh metadata].</param>
         /// <returns>Task{Genre}.</returns>
-        internal Task<Genre> GetGenre(string name, CancellationToken cancellationToken, bool allowSlowProviders = false, bool refreshMetadata = false)
+        public Genre GetGenre(string name)
         {
-            return GetItemByName<Genre>(ConfigurationManager.ApplicationPaths.GenrePath, name, cancellationToken, allowSlowProviders, refreshMetadata);
+            return GetItemByName<Genre>(ConfigurationManager.ApplicationPaths.GenrePath, name);
         }
 
         /// <summary>
         /// Gets the genre.
         /// </summary>
         /// <param name="name">The name.</param>
-        /// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
         /// <returns>Task{MusicGenre}.</returns>
-        public Task<MusicGenre> GetMusicGenre(string name, bool allowSlowProviders = false)
+        public MusicGenre GetMusicGenre(string name)
         {
-            return GetMusicGenre(name, CancellationToken.None, allowSlowProviders);
-        }
-
-        /// <summary>
-        /// Gets the music genre.
-        /// </summary>
-        /// <param name="name">The name.</param>
-        /// <param name="cancellationToken">The cancellation token.</param>
-        /// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
-        /// <param name="refreshMetadata">if set to <c>true</c> [refresh metadata].</param>
-        /// <returns>Task{MusicGenre}.</returns>
-        internal Task<MusicGenre> GetMusicGenre(string name, CancellationToken cancellationToken, bool allowSlowProviders = false, bool refreshMetadata = false)
-        {
-            return GetItemByName<MusicGenre>(ConfigurationManager.ApplicationPaths.MusicGenrePath, name, cancellationToken, allowSlowProviders, refreshMetadata);
+            return GetItemByName<MusicGenre>(ConfigurationManager.ApplicationPaths.MusicGenrePath, name);
         }
 
         /// <summary>
         /// Gets the game genre.
         /// </summary>
         /// <param name="name">The name.</param>
-        /// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
         /// <returns>Task{GameGenre}.</returns>
-        public Task<GameGenre> GetGameGenre(string name, bool allowSlowProviders = false)
+        public GameGenre GetGameGenre(string name)
         {
-            return GetGameGenre(name, CancellationToken.None, allowSlowProviders);
-        }
-
-        /// <summary>
-        /// Gets the game genre.
-        /// </summary>
-        /// <param name="name">The name.</param>
-        /// <param name="cancellationToken">The cancellation token.</param>
-        /// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
-        /// <param name="refreshMetadata">if set to <c>true</c> [refresh metadata].</param>
-        /// <returns>Task{GameGenre}.</returns>
-        internal Task<GameGenre> GetGameGenre(string name, CancellationToken cancellationToken, bool allowSlowProviders = false, bool refreshMetadata = false)
-        {
-            return GetItemByName<GameGenre>(ConfigurationManager.ApplicationPaths.GameGenrePath, name, cancellationToken, allowSlowProviders, refreshMetadata);
+            return GetItemByName<GameGenre>(ConfigurationManager.ApplicationPaths.GameGenrePath, name);
         }
 
         /// <summary>
         /// Gets a Genre
         /// </summary>
         /// <param name="name">The name.</param>
-        /// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
         /// <returns>Task{Genre}.</returns>
-        public Task<Artist> GetArtist(string name, bool allowSlowProviders = false)
+        public Artist GetArtist(string name)
         {
-            return GetArtist(name, CancellationToken.None, allowSlowProviders);
-        }
-
-        /// <summary>
-        /// Gets the artist.
-        /// </summary>
-        /// <param name="name">The name.</param>
-        /// <param name="cancellationToken">The cancellation token.</param>
-        /// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
-        /// <param name="refreshMetadata">if set to <c>true</c> [force creation].</param>
-        /// <returns>Task{Artist}.</returns>
-        internal Task<Artist> GetArtist(string name, CancellationToken cancellationToken, bool allowSlowProviders = false, bool refreshMetadata = false)
-        {
-            return GetItemByName<Artist>(ConfigurationManager.ApplicationPaths.ArtistsPath, name, cancellationToken, allowSlowProviders, refreshMetadata);
+            return GetItemByName<Artist>(ConfigurationManager.ApplicationPaths.ArtistsPath, name);
         }
 
         /// <summary>
@@ -739,17 +655,16 @@ namespace MediaBrowser.Server.Implementations.Library
         /// Gets a Year
         /// </summary>
         /// <param name="value">The value.</param>
-        /// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
         /// <returns>Task{Year}.</returns>
         /// <exception cref="System.ArgumentOutOfRangeException"></exception>
-        public Task<Year> GetYear(int value, bool allowSlowProviders = false)
+        public Year GetYear(int value)
         {
             if (value <= 0)
             {
                 throw new ArgumentOutOfRangeException();
             }
 
-            return GetItemByName<Year>(ConfigurationManager.ApplicationPaths.YearPath, value.ToString(UsCulture), CancellationToken.None, allowSlowProviders);
+            return GetItemByName<Year>(ConfigurationManager.ApplicationPaths.YearPath, value.ToString(UsCulture));
         }
 
         /// <summary>
@@ -940,7 +855,9 @@ namespace MediaBrowser.Server.Implementations.Library
 
                     try
                     {
-                        await GetPerson(currentPerson.Name, cancellationToken, true, true).ConfigureAwait(false);
+                        var item = GetPerson(currentPerson.Name);
+
+                        await item.RefreshMetadata(cancellationToken).ConfigureAwait(false);
                     }
                     catch (IOException ex)
                     {
@@ -964,6 +881,10 @@ namespace MediaBrowser.Server.Implementations.Library
             progress.Report(100);
 
             _logger.Info("People validation complete");
+
+            // Bad practice, i know. But we keep a lot in memory, unfortunately.
+            GC.Collect(2, GCCollectionMode.Forced, true);
+            GC.Collect(2, GCCollectionMode.Forced, true);
         }
 
         /// <summary>

+ 10 - 8
MediaBrowser.Server.Implementations/Library/LuceneSearchEngine.cs

@@ -97,7 +97,7 @@ namespace MediaBrowser.Server.Implementations.Library
         /// <param name="searchTerm">The search term.</param>
         /// <returns>IEnumerable{SearchHintResult}.</returns>
         /// <exception cref="System.ArgumentNullException">searchTerm</exception>
-        public async Task<IEnumerable<SearchHintInfo>> GetSearchHints(IEnumerable<BaseItem> inputItems, string searchTerm)
+        public Task<IEnumerable<SearchHintInfo>> GetSearchHints(IEnumerable<BaseItem> inputItems, string searchTerm)
         {
             if (string.IsNullOrEmpty(searchTerm))
             {
@@ -143,7 +143,7 @@ namespace MediaBrowser.Server.Implementations.Library
                 {
                     try
                     {
-                        var artist = await _libraryManager.GetArtist(item).ConfigureAwait(false);
+                        var artist = _libraryManager.GetArtist(item);
 
                         hints.Add(new Tuple<BaseItem, string, int>(artist, index.Item1, index.Item2));
                     }
@@ -169,7 +169,7 @@ namespace MediaBrowser.Server.Implementations.Library
                 {
                     try
                     {
-                        var genre = await _libraryManager.GetGenre(item).ConfigureAwait(false);
+                        var genre = _libraryManager.GetGenre(item);
 
                         hints.Add(new Tuple<BaseItem, string, int>(genre, index.Item1, index.Item2));
                     }
@@ -195,7 +195,7 @@ namespace MediaBrowser.Server.Implementations.Library
                 {
                     try
                     {
-                        var genre = await _libraryManager.GetMusicGenre(item).ConfigureAwait(false);
+                        var genre = _libraryManager.GetMusicGenre(item);
 
                         hints.Add(new Tuple<BaseItem, string, int>(genre, index.Item1, index.Item2));
                     }
@@ -221,7 +221,7 @@ namespace MediaBrowser.Server.Implementations.Library
                 {
                     try
                     {
-                        var genre = await _libraryManager.GetGameGenre(item).ConfigureAwait(false);
+                        var genre = _libraryManager.GetGameGenre(item);
 
                         hints.Add(new Tuple<BaseItem, string, int>(genre, index.Item1, index.Item2));
                     }
@@ -246,7 +246,7 @@ namespace MediaBrowser.Server.Implementations.Library
                 {
                     try
                     {
-                        var studio = await _libraryManager.GetStudio(item).ConfigureAwait(false);
+                        var studio = _libraryManager.GetStudio(item);
 
                         hints.Add(new Tuple<BaseItem, string, int>(studio, index.Item1, index.Item2));
                     }
@@ -272,7 +272,7 @@ namespace MediaBrowser.Server.Implementations.Library
                 {
                     try
                     {
-                        var person = await _libraryManager.GetPerson(item).ConfigureAwait(false);
+                        var person = _libraryManager.GetPerson(item);
 
                         hints.Add(new Tuple<BaseItem, string, int>(person, index.Item1, index.Item2));
                     }
@@ -283,11 +283,13 @@ namespace MediaBrowser.Server.Implementations.Library
                 }
             }
 
-            return hints.Where(i => i.Item3 >= 0).OrderBy(i => i.Item3).Select(i => new SearchHintInfo
+            var returnValue = hints.Where(i => i.Item3 >= 0).OrderBy(i => i.Item3).Select(i => new SearchHintInfo
             {
                 Item = i.Item1,
                 MatchedTerm = i.Item2
             });
+
+            return Task.FromResult(returnValue);
         }
 
         /// <summary>

+ 7 - 6
MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs

@@ -24,7 +24,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
         /// <summary>
         /// The _library manager
         /// </summary>
-        private readonly LibraryManager _libraryManager;
+        private readonly ILibraryManager _libraryManager;
 
         /// <summary>
         /// The _user manager
@@ -42,7 +42,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
         /// <param name="libraryManager">The library manager.</param>
         /// <param name="userManager">The user manager.</param>
         /// <param name="logger">The logger.</param>
-        public ArtistsValidator(LibraryManager libraryManager, IUserManager userManager, ILogger logger)
+        public ArtistsValidator(ILibraryManager libraryManager, IUserManager userManager, ILogger logger)
         {
             _libraryManager = libraryManager;
             _userManager = userManager;
@@ -65,7 +65,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
             var innerProgress = new ActionableProgress<double>();
 
             innerProgress.RegisterAction(pct => progress.Report(pct * .8));
-            
+
             var allArtists = await GetAllArtists(allSongs, cancellationToken, innerProgress).ConfigureAwait(false);
 
             progress.Report(80);
@@ -79,7 +79,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
             foreach (var artist in allArtists)
             {
                 cancellationToken.ThrowIfCancellationRequested();
-                
+
                 artist.ValidateImages();
                 artist.ValidateBackdrops();
 
@@ -230,8 +230,9 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
 
                     try
                     {
-                        var artistItem = await _libraryManager.GetArtist(currentArtist, cancellationToken, true, true)
-                            .ConfigureAwait(false);
+                        var artistItem = _libraryManager.GetArtist(currentArtist);
+
+                        await artistItem.RefreshMetadata(cancellationToken).ConfigureAwait(false);
 
                         returnArtists.Add(artistItem);
                     }

+ 5 - 5
MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs

@@ -14,7 +14,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
         /// <summary>
         /// The _library manager
         /// </summary>
-        private readonly LibraryManager _libraryManager;
+        private readonly ILibraryManager _libraryManager;
 
         /// <summary>
         /// The _user manager
@@ -26,7 +26,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
         /// </summary>
         private readonly ILogger _logger;
 
-        public GameGenresValidator(LibraryManager libraryManager, IUserManager userManager, ILogger logger)
+        public GameGenresValidator(ILibraryManager libraryManager, IUserManager userManager, ILogger logger)
         {
             _libraryManager = libraryManager;
             _userManager = userManager;
@@ -47,8 +47,6 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
                 .Select(i => new Tuple<Guid, List<Game>>(i.Id, i.RootFolder.GetRecursiveChildren(i).OfType<Game>().ToList()))
                 .ToList();
 
-            var allLibraryItems = allItems;
-
             var masterDictionary = new Dictionary<string, Dictionary<Guid, Dictionary<CountType, int>>>(StringComparer.OrdinalIgnoreCase);
 
             // Populate counts of items
@@ -99,7 +97,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
 
         private async Task UpdateItemByNameCounts(string name, CancellationToken cancellationToken, Dictionary<Guid, Dictionary<CountType, int>> counts)
         {
-            var itemByName = await _libraryManager.GetGameGenre(name, cancellationToken, true, true).ConfigureAwait(false);
+            var itemByName = _libraryManager.GetGameGenre(name);
 
             foreach (var libraryId in counts.Keys)
             {
@@ -107,6 +105,8 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
 
                 itemByName.UserItemCounts[libraryId] = itemCounts;
             }
+
+            await itemByName.RefreshMetadata(cancellationToken).ConfigureAwait(false);
         }
 
         private void SetItemCounts(Guid userId, IEnumerable<BaseItem> allItems, Dictionary<string, Dictionary<Guid, Dictionary<CountType, int>>> masterDictionary)

+ 5 - 3
MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs

@@ -15,7 +15,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
         /// <summary>
         /// The _library manager
         /// </summary>
-        private readonly LibraryManager _libraryManager;
+        private readonly ILibraryManager _libraryManager;
 
         /// <summary>
         /// The _user manager
@@ -27,7 +27,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
         /// </summary>
         private readonly ILogger _logger;
 
-        public GenresValidator(LibraryManager libraryManager, IUserManager userManager, ILogger logger)
+        public GenresValidator(ILibraryManager libraryManager, IUserManager userManager, ILogger logger)
         {
             _libraryManager = libraryManager;
             _userManager = userManager;
@@ -102,7 +102,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
 
         private async Task UpdateItemByNameCounts(string name, CancellationToken cancellationToken, Dictionary<Guid, Dictionary<CountType, int>> counts)
         {
-            var itemByName = await _libraryManager.GetGenre(name, cancellationToken, true, true).ConfigureAwait(false);
+            var itemByName = _libraryManager.GetGenre(name);
 
             foreach (var libraryId in counts.Keys)
             {
@@ -110,6 +110,8 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
 
                 itemByName.UserItemCounts[libraryId] = itemCounts;
             }
+
+            await itemByName.RefreshMetadata(cancellationToken).ConfigureAwait(false);
         }
 
         private void SetItemCounts(Guid userId, IEnumerable<BaseItem> allItems, Dictionary<string, Dictionary<Guid, Dictionary<CountType, int>>> masterDictionary)

+ 5 - 3
MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs

@@ -15,7 +15,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
         /// <summary>
         /// The _library manager
         /// </summary>
-        private readonly LibraryManager _libraryManager;
+        private readonly ILibraryManager _libraryManager;
 
         /// <summary>
         /// The _user manager
@@ -27,7 +27,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
         /// </summary>
         private readonly ILogger _logger;
 
-        public MusicGenresValidator(LibraryManager libraryManager, IUserManager userManager, ILogger logger)
+        public MusicGenresValidator(ILibraryManager libraryManager, IUserManager userManager, ILogger logger)
         {
             _libraryManager = libraryManager;
             _userManager = userManager;
@@ -102,7 +102,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
 
         private async Task UpdateItemByNameCounts(string name, CancellationToken cancellationToken, Dictionary<Guid, Dictionary<CountType, int>> counts)
         {
-            var itemByName = await _libraryManager.GetMusicGenre(name, cancellationToken, true, true).ConfigureAwait(false);
+            var itemByName = _libraryManager.GetMusicGenre(name);
 
             foreach (var libraryId in counts.Keys)
             {
@@ -110,6 +110,8 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
 
                 itemByName.UserItemCounts[libraryId] = itemCounts;
             }
+
+            await itemByName.RefreshMetadata(cancellationToken).ConfigureAwait(false);
         }
 
         private void SetItemCounts(Guid userId, IEnumerable<BaseItem> allItems, Dictionary<string, Dictionary<Guid, Dictionary<CountType, int>>> masterDictionary)

+ 3 - 4
MediaBrowser.Server.Implementations/Library/Validators/PeoplePostScanTask.cs

@@ -41,11 +41,10 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
         /// <returns>Task.</returns>
         public Task Run(IProgress<double> progress, CancellationToken cancellationToken)
         {
-            return RunInternal(progress, cancellationToken);
-            //return Task.Run(() => RunInternal(progress, cancellationToken));
+            return Task.Run(() => RunInternal(progress, cancellationToken));
         }
 
-        private async Task RunInternal(IProgress<double> progress, CancellationToken cancellationToken)
+        private void RunInternal(IProgress<double> progress, CancellationToken cancellationToken)
         {
             var allItems = _libraryManager.RootFolder.RecursiveChildren.ToList();
 
@@ -91,7 +90,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
                 {
                     var counts = masterDictionary[name];
 
-                    var itemByName = await _libraryManager.GetPerson(name).ConfigureAwait(false);
+                    var itemByName = _libraryManager.GetPerson(name);
 
                     foreach (var libraryId in counts.Keys)
                     {

+ 5 - 3
MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs

@@ -14,7 +14,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
         /// <summary>
         /// The _library manager
         /// </summary>
-        private readonly LibraryManager _libraryManager;
+        private readonly ILibraryManager _libraryManager;
 
         /// <summary>
         /// The _user manager
@@ -26,7 +26,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
         /// </summary>
         private readonly ILogger _logger;
 
-        public StudiosValidator(LibraryManager libraryManager, IUserManager userManager, ILogger logger)
+        public StudiosValidator(ILibraryManager libraryManager, IUserManager userManager, ILogger logger)
         {
             _libraryManager = libraryManager;
             _userManager = userManager;
@@ -99,7 +99,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
 
         private async Task UpdateItemByNameCounts(string name, CancellationToken cancellationToken, Dictionary<Guid, Dictionary<CountType, int>> counts)
         {
-            var itemByName = await _libraryManager.GetStudio(name, cancellationToken, true, true).ConfigureAwait(false);
+            var itemByName = _libraryManager.GetStudio(name);
 
             foreach (var libraryId in counts.Keys)
             {
@@ -107,6 +107,8 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
 
                 itemByName.UserItemCounts[libraryId] = itemCounts;
             }
+
+            await itemByName.RefreshMetadata(cancellationToken).ConfigureAwait(false);
         }
 
         private void SetItemCounts(Guid userId, IEnumerable<BaseItem> allItems, Dictionary<string, Dictionary<Guid, Dictionary<CountType, int>>> masterDictionary)