Luke Pulverenti преди 9 години
родител
ревизия
759f5a8560
променени са 58 файла, в които са добавени 404 реда и са изтрити 355 реда
  1. 0 11
      Emby.Drawing/ImageMagick/ImageMagickEncoder.cs
  2. 1 1
      MediaBrowser.Api/BaseApiService.cs
  3. 5 4
      MediaBrowser.Api/GamesService.cs
  4. 5 5
      MediaBrowser.Api/Images/ImageService.cs
  5. 5 5
      MediaBrowser.Api/Images/RemoteImageService.cs
  6. 18 18
      MediaBrowser.Api/ItemLookupService.cs
  7. 3 3
      MediaBrowser.Api/Library/LibraryService.cs
  8. 1 1
      MediaBrowser.Api/LiveTv/LiveTvService.cs
  9. 9 9
      MediaBrowser.Api/Movies/MoviesService.cs
  10. 7 6
      MediaBrowser.Api/Music/AlbumsService.cs
  11. 11 10
      MediaBrowser.Api/Music/InstantMixService.cs
  12. 7 5
      MediaBrowser.Api/PackageReviewService.cs
  13. 2 2
      MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
  14. 1 1
      MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
  15. 5 4
      MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs
  16. 3 2
      MediaBrowser.Api/Playback/Progressive/AudioService.cs
  17. 15 13
      MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
  18. 3 2
      MediaBrowser.Api/Playback/Progressive/VideoService.cs
  19. 2 2
      MediaBrowser.Api/PlaylistService.cs
  20. 7 5
      MediaBrowser.Api/SimilarItemsHelper.cs
  21. 5 5
      MediaBrowser.Api/Subtitles/SubtitleService.cs
  22. 6 8
      MediaBrowser.Api/Sync/SyncService.cs
  23. 1 1
      MediaBrowser.Api/System/SystemService.cs
  24. 13 12
      MediaBrowser.Api/TvShowsService.cs
  25. 1 1
      MediaBrowser.Api/UserLibrary/ItemsService.cs
  26. 3 3
      MediaBrowser.Api/UserLibrary/PlaystateService.cs
  27. 6 6
      MediaBrowser.Api/UserLibrary/UserLibraryService.cs
  28. 2 1
      MediaBrowser.Controller/Dto/IDtoService.cs
  29. 3 1
      MediaBrowser.Controller/Entities/BaseItem.cs
  30. 19 5
      MediaBrowser.Controller/Entities/Folder.cs
  31. 2 1
      MediaBrowser.Controller/Entities/IHasUserData.cs
  32. 3 2
      MediaBrowser.Controller/IServerApplicationHost.cs
  33. 3 1
      MediaBrowser.Controller/Library/IUserDataManager.cs
  34. 4 4
      MediaBrowser.Controller/Net/IHttpResultFactory.cs
  35. 2 2
      MediaBrowser.Dlna/Didl/DidlBuilder.cs
  36. 7 6
      MediaBrowser.Dlna/Main/DlnaEntryPoint.cs
  37. 17 18
      MediaBrowser.Dlna/PlayTo/PlayToController.cs
  38. 2 2
      MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs
  39. 5 2
      MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs
  40. 15 14
      MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs
  41. 7 4
      MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs
  42. 4 4
      MediaBrowser.Server.Implementations/Channels/ChannelManager.cs
  43. 8 6
      MediaBrowser.Server.Implementations/Connect/ConnectManager.cs
  44. 43 52
      MediaBrowser.Server.Implementations/Dto/DtoService.cs
  45. 17 11
      MediaBrowser.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs
  46. 1 1
      MediaBrowser.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs
  47. 5 5
      MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs
  48. 1 1
      MediaBrowser.Server.Implementations/HttpServer/SwaggerService.cs
  49. 1 1
      MediaBrowser.Server.Implementations/Library/LibraryManager.cs
  50. 11 2
      MediaBrowser.Server.Implementations/Library/UserDataManager.cs
  51. 1 1
      MediaBrowser.Server.Implementations/Library/UserManager.cs
  52. 3 3
      MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
  53. 1 1
      MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
  54. 19 10
      MediaBrowser.Server.Implementations/Session/SessionManager.cs
  55. 23 9
      MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs
  56. 6 6
      MediaBrowser.Server.Implementations/Udp/UdpServer.cs
  57. 19 30
      MediaBrowser.Server.Startup.Common/ApplicationHost.cs
  58. 5 4
      MediaBrowser.WebDashboard/Api/DashboardService.cs

+ 0 - 11
Emby.Drawing/ImageMagick/ImageMagickEncoder.cs

@@ -111,7 +111,6 @@ namespace Emby.Drawing.ImageMagick
                 wand.CurrentImage.TrimImage(10);
                 wand.SaveImage(outputPath);
             }
-            SaveDelay();
         }
 
         public ImageSize GetImageSize(string path)
@@ -189,7 +188,6 @@ namespace Emby.Drawing.ImageMagick
                     }
                 }
             }
-            SaveDelay();
         }
 
         private void AddForegroundLayer(MagickWand wand, ImageProcessingOptions options)
@@ -294,15 +292,6 @@ namespace Emby.Drawing.ImageMagick
             {
                 new StripCollageBuilder(_appPaths, _fileSystem).BuildPosterCollage(options.InputPaths.ToList(), options.OutputPath, options.Width, options.Height);
             }
-
-            SaveDelay();
-        }
-
-        private void SaveDelay()
-        {
-            // For some reason the images are not always getting released right away
-            //var task = Task.Delay(300);
-            //Task.WaitAll(task);
         }
 
         public string Name

+ 1 - 1
MediaBrowser.Api/BaseApiService.cs

@@ -115,7 +115,7 @@ namespace MediaBrowser.Api
         /// <returns>System.Object.</returns>
         protected object ToStaticFileResult(string path)
         {
-            return ResultFactory.GetStaticFileResult(Request, path);
+            return ResultFactory.GetStaticFileResult(Request, path).Result;
         }
 
         protected DtoOptions GetDtoOptions(object request)

+ 5 - 4
MediaBrowser.Api/GamesService.cs

@@ -10,6 +10,7 @@ using System.Collections.Generic;
 using System.Globalization;
 using System.IO;
 using System.Linq;
+using System.Threading.Tasks;
 using MediaBrowser.Model.Querying;
 
 namespace MediaBrowser.Api
@@ -186,14 +187,14 @@ namespace MediaBrowser.Api
         /// </summary>
         /// <param name="request">The request.</param>
         /// <returns>System.Object.</returns>
-        public object Get(GetSimilarGames request)
+        public async Task<object> Get(GetSimilarGames request)
         {
-            var result = GetSimilarItemsResult(request);
+            var result = await GetSimilarItemsResult(request).ConfigureAwait(false);
 
             return ToOptimizedSerializedResultUsingCache(result);
         }
 
-        private QueryResult<BaseItemDto> GetSimilarItemsResult(BaseGetSimilarItemsFromItem request)
+        private async Task<QueryResult<BaseItemDto>> GetSimilarItemsResult(BaseGetSimilarItemsFromItem request)
         {
             var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null;
 
@@ -216,7 +217,7 @@ namespace MediaBrowser.Api
 
             var result = new QueryResult<BaseItemDto>
             {
-                Items = _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ToArray(),
+                Items = (await _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ConfigureAwait(false)).ToArray(),
 
                 TotalRecordCount = itemsResult.Count
             };

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

@@ -514,7 +514,7 @@ namespace MediaBrowser.Api.Images
         /// <param name="isHeadRequest">if set to <c>true</c> [is head request].</param>
         /// <returns>System.Object.</returns>
         /// <exception cref="ResourceNotFoundException"></exception>
-        public object GetImage(ImageRequest request, IHasImages item, bool isHeadRequest)
+        public Task<object> GetImage(ImageRequest request, IHasImages item, bool isHeadRequest)
         {
             if (request.PercentPlayed.HasValue)
             {
@@ -594,8 +594,7 @@ namespace MediaBrowser.Api.Images
                 supportedImageEnhancers,
                 cacheDuration,
                 responseHeaders,
-                isHeadRequest)
-                .Result;
+                isHeadRequest);
         }
 
         private async Task<object> GetImageResult(IHasImages item,
@@ -632,7 +631,7 @@ namespace MediaBrowser.Api.Images
 
             headers["Vary"] = "Accept";
 
-            return ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
+            return await ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
             {
                 CacheDuration = cacheDuration,
                 ResponseHeaders = headers,
@@ -643,7 +642,8 @@ namespace MediaBrowser.Api.Images
                 // Sometimes imagemagick keeps a hold on the file briefly even after it's done writing to it.
                 // I'd rather do this than add a delay after saving the file
                 FileShare = FileShare.ReadWrite
-            });
+
+            }).ConfigureAwait(false);
         }
 
         private List<ImageFormat> GetOutputFormats(ImageRequest request, ItemImageInfo image, bool cropwhitespace, List<IImageEnhancer> enhancers)

+ 5 - 5
MediaBrowser.Api/Images/RemoteImageService.cs

@@ -238,9 +238,9 @@ namespace MediaBrowser.Api.Images
                 }
 
 				if (_fileSystem.FileExists(contentPath))
-                {
-                    return ToStaticFileResult(contentPath);
-                }
+				{
+				    return await ResultFactory.GetStaticFileResult(Request, contentPath).ConfigureAwait(false);
+				}
             }
             catch (DirectoryNotFoundException)
             {
@@ -259,9 +259,9 @@ namespace MediaBrowser.Api.Images
                 contentPath = await reader.ReadToEndAsync().ConfigureAwait(false);
             }
 
-            return ToStaticFileResult(contentPath);
+            return await ResultFactory.GetStaticFileResult(Request, contentPath).ConfigureAwait(false);
         }
-        
+
         /// <summary>
         /// Downloads the image.
         /// </summary>

+ 18 - 18
MediaBrowser.Api/ItemLookupService.cs

@@ -132,58 +132,58 @@ namespace MediaBrowser.Api
             return ToOptimizedResult(infos);
         }
 
-        public object Post(GetMovieRemoteSearchResults request)
+        public async Task<object> Post(GetMovieRemoteSearchResults request)
         {
-            var result = _providerManager.GetRemoteSearchResults<Movie, MovieInfo>(request, CancellationToken.None).Result;
+            var result = await _providerManager.GetRemoteSearchResults<Movie, MovieInfo>(request, CancellationToken.None).ConfigureAwait(false);
 
             return ToOptimizedResult(result);
         }
 
-        public object Post(GetSeriesRemoteSearchResults request)
+        public async Task<object> Post(GetSeriesRemoteSearchResults request)
         {
-            var result = _providerManager.GetRemoteSearchResults<Series, SeriesInfo>(request, CancellationToken.None).Result;
+            var result = await _providerManager.GetRemoteSearchResults<Series, SeriesInfo>(request, CancellationToken.None).ConfigureAwait(false);
 
             return ToOptimizedResult(result);
         }
 
-        public object Post(GetGameRemoteSearchResults request)
+        public async Task<object> Post(GetGameRemoteSearchResults request)
         {
-            var result = _providerManager.GetRemoteSearchResults<Game, GameInfo>(request, CancellationToken.None).Result;
+            var result = await _providerManager.GetRemoteSearchResults<Game, GameInfo>(request, CancellationToken.None).ConfigureAwait(false);
 
             return ToOptimizedResult(result);
         }
 
-        public object Post(GetBoxSetRemoteSearchResults request)
+        public async Task<object> Post(GetBoxSetRemoteSearchResults request)
         {
-            var result = _providerManager.GetRemoteSearchResults<BoxSet, BoxSetInfo>(request, CancellationToken.None).Result;
+            var result = await _providerManager.GetRemoteSearchResults<BoxSet, BoxSetInfo>(request, CancellationToken.None).ConfigureAwait(false);
 
             return ToOptimizedResult(result);
         }
 
-        public object Post(GetPersonRemoteSearchResults request)
+        public async Task<object> Post(GetPersonRemoteSearchResults request)
         {
-            var result = _providerManager.GetRemoteSearchResults<Person, PersonLookupInfo>(request, CancellationToken.None).Result;
+            var result = await _providerManager.GetRemoteSearchResults<Person, PersonLookupInfo>(request, CancellationToken.None).ConfigureAwait(false);
 
             return ToOptimizedResult(result);
         }
 
-        public object Post(GetMusicAlbumRemoteSearchResults request)
+        public async Task<object> Post(GetMusicAlbumRemoteSearchResults request)
         {
-            var result = _providerManager.GetRemoteSearchResults<MusicAlbum, AlbumInfo>(request, CancellationToken.None).Result;
+            var result = await _providerManager.GetRemoteSearchResults<MusicAlbum, AlbumInfo>(request, CancellationToken.None).ConfigureAwait(false);
 
             return ToOptimizedResult(result);
         }
 
-        public object Post(GetMusicArtistRemoteSearchResults request)
+        public async Task<object> Post(GetMusicArtistRemoteSearchResults request)
         {
-            var result = _providerManager.GetRemoteSearchResults<MusicArtist, ArtistInfo>(request, CancellationToken.None).Result;
+            var result = await _providerManager.GetRemoteSearchResults<MusicArtist, ArtistInfo>(request, CancellationToken.None).ConfigureAwait(false);
 
             return ToOptimizedResult(result);
         }
 
-        public object Get(GetRemoteSearchImage request)
+        public async Task<object> Get(GetRemoteSearchImage request)
         {
-            var result = GetRemoteImage(request).Result;
+            var result = GetRemoteImage(request).ConfigureAwait(false);
 
             return result;
         }
@@ -241,7 +241,7 @@ namespace MediaBrowser.Api
 
                 if (_fileSystem.FileExists(contentPath))
                 {
-                    return ToStaticFileResult(contentPath);
+                    return await ResultFactory.GetStaticFileResult(Request, contentPath).ConfigureAwait(false);
                 }
             }
             catch (DirectoryNotFoundException)
@@ -261,7 +261,7 @@ namespace MediaBrowser.Api
                 contentPath = await reader.ReadToEndAsync().ConfigureAwait(false);
             }
 
-            return ToStaticFileResult(contentPath);
+            return await ResultFactory.GetStaticFileResult(Request, contentPath).ConfigureAwait(false);
         }
 
         /// <summary>

+ 3 - 3
MediaBrowser.Api/Library/LibraryService.cs

@@ -493,7 +493,7 @@ namespace MediaBrowser.Api.Library
             }
         }
 
-        public object Get(GetDownload request)
+        public Task<object> Get(GetDownload request)
         {
             var item = _libraryManager.GetItemById(request.Id);
             var auth = _authContext.GetAuthorizationInfo(Request);
@@ -552,7 +552,7 @@ namespace MediaBrowser.Api.Library
             }
         }
 
-        public object Get(GetFile request)
+        public Task<object> Get(GetFile request)
         {
             var item = _libraryManager.GetItemById(request.Id);
             var locationType = item.LocationType;
@@ -565,7 +565,7 @@ namespace MediaBrowser.Api.Library
                 throw new ArgumentException("This command cannot be used for directories.");
             }
 
-            return ToStaticFileResult(item.Path);
+            return ResultFactory.GetStaticFileResult(Request, item.Path);
         }
 
         /// <summary>

+ 1 - 1
MediaBrowser.Api/LiveTv/LiveTvService.cs

@@ -785,7 +785,7 @@ namespace MediaBrowser.Api.LiveTv
 
             var user = string.IsNullOrEmpty(request.UserId) ? null : _userManager.GetUserById(request.UserId);
 
-            var returnArray = _dtoService.GetBaseItemDtos(channelResult.Items, GetDtoOptions(Request), user).ToArray();
+            var returnArray = (await _dtoService.GetBaseItemDtos(channelResult.Items, GetDtoOptions(Request), user).ConfigureAwait(false)).ToArray();
 
             var result = new QueryResult<BaseItemDto>
             {

+ 9 - 9
MediaBrowser.Api/Movies/MoviesService.cs

@@ -111,16 +111,16 @@ namespace MediaBrowser.Api.Movies
         /// </summary>
         /// <param name="request">The request.</param>
         /// <returns>System.Object.</returns>
-        public object Get(GetSimilarMovies request)
+        public async Task<object> Get(GetSimilarMovies request)
         {
-            var result = GetSimilarItemsResult(request);
+            var result = await GetSimilarItemsResult(request).ConfigureAwait(false);
 
             return ToOptimizedSerializedResultUsingCache(result);
         }
 
-        public object Get(GetSimilarTrailers request)
+        public async Task<object> Get(GetSimilarTrailers request)
         {
-            var result = GetSimilarItemsResult(request);
+            var result = await GetSimilarItemsResult(request).ConfigureAwait(false);
 
             return ToOptimizedSerializedResultUsingCache(result);
         }
@@ -138,7 +138,7 @@ namespace MediaBrowser.Api.Movies
             return ToOptimizedResult(result);
         }
 
-        private QueryResult<BaseItemDto> GetSimilarItemsResult(BaseGetSimilarItemsFromItem request)
+        private async Task<QueryResult<BaseItemDto>> GetSimilarItemsResult(BaseGetSimilarItemsFromItem request)
         {
             var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null;
 
@@ -163,7 +163,7 @@ namespace MediaBrowser.Api.Movies
 
             var result = new QueryResult<BaseItemDto>
             {
-                Items = _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ToArray(),
+                Items = (await _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ConfigureAwait(false)).ToArray(),
 
                 TotalRecordCount = itemsResult.Count
             };
@@ -296,7 +296,7 @@ namespace MediaBrowser.Api.Movies
                         BaselineItemName = name,
                         CategoryId = name.GetMD5().ToString("N"),
                         RecommendationType = type,
-                        Items = _dtoService.GetBaseItemDtos(items, dtoOptions, user).ToArray()
+                        Items = _dtoService.GetBaseItemDtos(items, dtoOptions, user).Result.ToArray()
                     };
                 }
             }
@@ -330,7 +330,7 @@ namespace MediaBrowser.Api.Movies
                         BaselineItemName = name,
                         CategoryId = name.GetMD5().ToString("N"),
                         RecommendationType = type,
-                        Items = _dtoService.GetBaseItemDtos(items, dtoOptions, user).ToArray()
+                        Items = _dtoService.GetBaseItemDtos(items, dtoOptions, user).Result.ToArray()
                     };
                 }
             }
@@ -361,7 +361,7 @@ namespace MediaBrowser.Api.Movies
                         BaselineItemName = item.Name,
                         CategoryId = item.Id.ToString("N"),
                         RecommendationType = type,
-                        Items = _dtoService.GetBaseItemDtos(similar, dtoOptions, user).ToArray()
+                        Items = _dtoService.GetBaseItemDtos(similar, dtoOptions, user).Result.ToArray()
                     };
                 }
             }

+ 7 - 6
MediaBrowser.Api/Music/AlbumsService.cs

@@ -8,6 +8,7 @@ using ServiceStack;
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Threading.Tasks;
 
 namespace MediaBrowser.Api.Music
 {
@@ -49,18 +50,18 @@ namespace MediaBrowser.Api.Music
             _dtoService = dtoService;
         }
 
-        public object Get(GetSimilarArtists request)
+        public async Task<object> Get(GetSimilarArtists request)
         {
             var dtoOptions = GetDtoOptions(request);
 
-            var result = SimilarItemsHelper.GetSimilarItemsResult(dtoOptions, _userManager,
+            var result = await SimilarItemsHelper.GetSimilarItemsResult(dtoOptions, _userManager,
                 _itemRepo,
                 _libraryManager,
                 _userDataRepository,
                 _dtoService,
                 Logger,
                 request, new[] { typeof(MusicArtist) },
-                SimilarItemsHelper.GetSimiliarityScore);
+                SimilarItemsHelper.GetSimiliarityScore).ConfigureAwait(false);
 
             return ToOptimizedSerializedResultUsingCache(result);
         }
@@ -70,18 +71,18 @@ namespace MediaBrowser.Api.Music
         /// </summary>
         /// <param name="request">The request.</param>
         /// <returns>System.Object.</returns>
-        public object Get(GetSimilarAlbums request)
+        public async Task<object> Get(GetSimilarAlbums request)
         {
             var dtoOptions = GetDtoOptions(request);
 
-            var result = SimilarItemsHelper.GetSimilarItemsResult(dtoOptions, _userManager,
+            var result = await SimilarItemsHelper.GetSimilarItemsResult(dtoOptions, _userManager,
                 _itemRepo,
                 _libraryManager,
                 _userDataRepository,
                 _dtoService,
                 Logger,
                 request, new[] { typeof(MusicAlbum) },
-                GetAlbumSimilarityScore);
+                GetAlbumSimilarityScore).ConfigureAwait(false);
 
             return ToOptimizedSerializedResultUsingCache(result);
         }

+ 11 - 10
MediaBrowser.Api/Music/InstantMixService.cs

@@ -8,6 +8,7 @@ using MediaBrowser.Model.Querying;
 using ServiceStack;
 using System.Collections.Generic;
 using System.Linq;
+using System.Threading.Tasks;
 
 namespace MediaBrowser.Api.Music
 {
@@ -76,7 +77,7 @@ namespace MediaBrowser.Api.Music
             _libraryManager = libraryManager;
         }
 
-        public object Get(GetInstantMixFromItem request)
+        public Task<object> Get(GetInstantMixFromItem request)
         {
             var item = _libraryManager.GetItemById(request.Id);
 
@@ -87,7 +88,7 @@ namespace MediaBrowser.Api.Music
             return GetResult(items, user, request);
         }
 
-        public object Get(GetInstantMixFromArtistId request)
+        public Task<object> Get(GetInstantMixFromArtistId request)
         {
             var item = _libraryManager.GetItemById(request.Id);
 
@@ -98,7 +99,7 @@ namespace MediaBrowser.Api.Music
             return GetResult(items, user, request);
         }
 
-        public object Get(GetInstantMixFromMusicGenreId request)
+        public Task<object> Get(GetInstantMixFromMusicGenreId request)
         {
             var item = _libraryManager.GetItemById(request.Id);
 
@@ -109,7 +110,7 @@ namespace MediaBrowser.Api.Music
             return GetResult(items, user, request);
         }
 
-        public object Get(GetInstantMixFromSong request)
+        public Task<object> Get(GetInstantMixFromSong request)
         {
             var item = _libraryManager.GetItemById(request.Id);
 
@@ -120,7 +121,7 @@ namespace MediaBrowser.Api.Music
             return GetResult(items, user, request);
         }
 
-        public object Get(GetInstantMixFromAlbum request)
+        public Task<object> Get(GetInstantMixFromAlbum request)
         {
             var album = _libraryManager.GetItemById(request.Id);
 
@@ -131,7 +132,7 @@ namespace MediaBrowser.Api.Music
             return GetResult(items, user, request);
         }
 
-        public object Get(GetInstantMixFromPlaylist request)
+        public Task<object> Get(GetInstantMixFromPlaylist request)
         {
             var playlist = (Playlist)_libraryManager.GetItemById(request.Id);
 
@@ -142,7 +143,7 @@ namespace MediaBrowser.Api.Music
             return GetResult(items, user, request);
         }
 
-        public object Get(GetInstantMixFromMusicGenre request)
+        public Task<object> Get(GetInstantMixFromMusicGenre request)
         {
             var user = _userManager.GetUserById(request.UserId);
 
@@ -151,7 +152,7 @@ namespace MediaBrowser.Api.Music
             return GetResult(items, user, request);
         }
 
-        public object Get(GetInstantMixFromArtist request)
+        public Task<object> Get(GetInstantMixFromArtist request)
         {
             var user = _userManager.GetUserById(request.UserId);
             var artist = _libraryManager.GetArtist(request.Name);
@@ -161,7 +162,7 @@ namespace MediaBrowser.Api.Music
             return GetResult(items, user, request);
         }
 
-        private object GetResult(IEnumerable<Audio> items, User user, BaseGetSimilarItems request)
+        private async Task<object> GetResult(IEnumerable<Audio> items, User user, BaseGetSimilarItems request)
         {
             var list = items.ToList();
 
@@ -172,7 +173,7 @@ namespace MediaBrowser.Api.Music
 
             var dtoOptions = GetDtoOptions(request);
 
-            result.Items = _dtoService.GetBaseItemDtos(list.Take(request.Limit ?? list.Count), dtoOptions, user).ToArray();
+            result.Items = (await _dtoService.GetBaseItemDtos(list.Take(request.Limit ?? list.Count), dtoOptions, user).ConfigureAwait(false)).ToArray();
 
             return ToOptimizedResult(result);
         }

+ 7 - 5
MediaBrowser.Api/PackageReviewService.cs

@@ -112,7 +112,7 @@ namespace MediaBrowser.Api
             _appHost = appHost;
         }
 
-        public object Get(ReviewRequest request)
+        public async Task<object> Get(ReviewRequest request)
         {
             var parms = "?id=" + request.Id;
 
@@ -133,11 +133,13 @@ namespace MediaBrowser.Api
                 parms += "&title=true";
             }
 
-            var result = _httpClient.Get(MbAdminUrl + "/service/packageReview/retrieve" + parms, CancellationToken.None).Result;
-
-            var reviews = _serializer.DeserializeFromStream<List<PackageReviewInfo>>(result);
+            using (var result = await _httpClient.Get(MbAdminUrl + "/service/packageReview/retrieve" + parms, CancellationToken.None)
+                            .ConfigureAwait(false))
+            {
+                var reviews = _serializer.DeserializeFromStream<List<PackageReviewInfo>>(result);
 
-            return ToOptimizedResult(reviews);
+                return ToOptimizedResult(reviews);
+            }
         }
 
         public void Post(CreateReviewRequest request)

+ 2 - 2
MediaBrowser.Api/Playback/Hls/BaseHlsService.cs

@@ -63,9 +63,9 @@ namespace MediaBrowser.Api.Playback.Hls
         /// <param name="request">The request.</param>
         /// <param name="isLive">if set to <c>true</c> [is live].</param>
         /// <returns>System.Object.</returns>
-        protected object ProcessRequest(StreamRequest request, bool isLive)
+        protected async Task<object> ProcessRequest(StreamRequest request, bool isLive)
         {
-            return ProcessRequestAsync(request, isLive).Result;
+            return await ProcessRequestAsync(request, isLive).ConfigureAwait(false);
         }
 
         /// <summary>

+ 1 - 1
MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs

@@ -475,7 +475,7 @@ namespace MediaBrowser.Api.Playback.Hls
                         ApiEntryPoint.Instance.OnTranscodeEndRequest(transcodingJob);
                     }
                 }
-            });
+            }).Result;
         }
 
         private async Task<object> GetMasterPlaylistInternal(StreamRequest request, string method)

+ 5 - 4
MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs

@@ -5,6 +5,7 @@ using ServiceStack;
 using System;
 using System.IO;
 using System.Linq;
+using System.Threading.Tasks;
 
 namespace MediaBrowser.Api.Playback.Hls
 {
@@ -89,7 +90,7 @@ namespace MediaBrowser.Api.Playback.Hls
             _config = config;
         }
 
-        public object Get(GetHlsPlaylistLegacy request)
+        public Task<object> Get(GetHlsPlaylistLegacy request)
         {
             var file = request.PlaylistId + Path.GetExtension(Request.PathInfo);
             file = Path.Combine(_appPaths.TranscodingTempPath, file);
@@ -107,7 +108,7 @@ namespace MediaBrowser.Api.Playback.Hls
         /// </summary>
         /// <param name="request">The request.</param>
         /// <returns>System.Object.</returns>
-        public object Get(GetHlsVideoSegmentLegacy request)
+        public Task<object> Get(GetHlsVideoSegmentLegacy request)
         {
             var file = request.SegmentId + Path.GetExtension(Request.PathInfo);
             file = Path.Combine(_config.ApplicationPaths.TranscodingTempPath, file);
@@ -131,10 +132,10 @@ namespace MediaBrowser.Api.Playback.Hls
             var file = request.SegmentId + Path.GetExtension(Request.PathInfo);
             file = Path.Combine(_appPaths.TranscodingTempPath, file);
 
-            return ResultFactory.GetStaticFileResult(Request, file, FileShare.ReadWrite);
+            return ResultFactory.GetStaticFileResult(Request, file, FileShare.ReadWrite).Result;
         }
 
-        private object GetFileResult(string path, string playlistPath)
+        private Task<object> GetFileResult(string path, string playlistPath)
         {
             var transcodingJob = ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlistPath, TranscodingJobType.Hls);
 

+ 3 - 2
MediaBrowser.Api/Playback/Progressive/AudioService.cs

@@ -9,6 +9,7 @@ using MediaBrowser.Model.IO;
 using MediaBrowser.Model.Serialization;
 using ServiceStack;
 using System.Collections.Generic;
+using System.Threading.Tasks;
 using CommonIO;
 
 namespace MediaBrowser.Api.Playback.Progressive
@@ -40,7 +41,7 @@ namespace MediaBrowser.Api.Playback.Progressive
         /// </summary>
         /// <param name="request">The request.</param>
         /// <returns>System.Object.</returns>
-        public object Get(GetAudioStream request)
+        public Task<object> Get(GetAudioStream request)
         {
             return ProcessRequest(request, false);
         }
@@ -50,7 +51,7 @@ namespace MediaBrowser.Api.Playback.Progressive
         /// </summary>
         /// <param name="request">The request.</param>
         /// <returns>System.Object.</returns>
-        public object Head(GetAudioStream request)
+        public Task<object> Head(GetAudioStream request)
         {
             return ProcessRequest(request, true);
         }

+ 15 - 13
MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs

@@ -113,11 +113,11 @@ namespace MediaBrowser.Api.Playback.Progressive
         /// <param name="request">The request.</param>
         /// <param name="isHeadRequest">if set to <c>true</c> [is head request].</param>
         /// <returns>Task.</returns>
-        protected object ProcessRequest(StreamRequest request, bool isHeadRequest)
+        protected async Task<object> ProcessRequest(StreamRequest request, bool isHeadRequest)
         {
             var cancellationTokenSource = new CancellationTokenSource();
 
-            var state = GetState(request, cancellationTokenSource.Token).Result;
+            var state = await GetState(request, cancellationTokenSource.Token).ConfigureAwait(false);
 
             var responseHeaders = new Dictionary<string, string>();
 
@@ -128,7 +128,8 @@ namespace MediaBrowser.Api.Playback.Progressive
 
                 using (state)
                 {
-                    return GetStaticRemoteStreamResult(state, responseHeaders, isHeadRequest, cancellationTokenSource).Result;
+                    return await GetStaticRemoteStreamResult(state, responseHeaders, isHeadRequest, cancellationTokenSource)
+                                .ConfigureAwait(false);
                 }
             }
 
@@ -138,7 +139,7 @@ namespace MediaBrowser.Api.Playback.Progressive
             }
 
             var outputPath = state.OutputFilePath;
-			var outputPathExists = FileSystem.FileExists(outputPath);
+            var outputPathExists = FileSystem.FileExists(outputPath);
 
             var isTranscodeCached = outputPathExists && !ApiEntryPoint.Instance.HasActiveTranscodingJob(outputPath, TranscodingJobType.Progressive);
 
@@ -151,13 +152,13 @@ namespace MediaBrowser.Api.Playback.Progressive
 
                 using (state)
                 {
-                    return ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
+                    return await ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
                     {
                         ResponseHeaders = responseHeaders,
                         ContentType = contentType,
                         IsHeadRequest = isHeadRequest,
                         Path = state.MediaPath
-                    });
+                    }).ConfigureAwait(false);
                 }
             }
 
@@ -168,13 +169,13 @@ namespace MediaBrowser.Api.Playback.Progressive
 
                 try
                 {
-                    return ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
+                    return await ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
                     {
                         ResponseHeaders = responseHeaders,
                         ContentType = contentType,
                         IsHeadRequest = isHeadRequest,
                         Path = outputPath
-                    });
+                    }).ConfigureAwait(false);
                 }
                 finally
                 {
@@ -185,7 +186,8 @@ namespace MediaBrowser.Api.Playback.Progressive
             // Need to start ffmpeg
             try
             {
-                return GetStreamResult(state, responseHeaders, isHeadRequest, cancellationTokenSource).Result;
+                return await GetStreamResult(state, responseHeaders, isHeadRequest, cancellationTokenSource)
+                            .ConfigureAwait(false);
             }
             catch
             {
@@ -229,7 +231,7 @@ namespace MediaBrowser.Api.Playback.Progressive
 
             if (trySupportSeek)
             {
-                foreach (var name in new[] {"Content-Range", "Accept-Ranges"})
+                foreach (var name in new[] { "Content-Range", "Accept-Ranges" })
                 {
                     var val = response.Headers[name];
                     if (!string.IsNullOrWhiteSpace(val))
@@ -242,12 +244,12 @@ namespace MediaBrowser.Api.Playback.Progressive
             {
                 responseHeaders["Accept-Ranges"] = "none";
             }
-            
+
             if (response.ContentLength.HasValue)
             {
                 responseHeaders["Content-Length"] = response.ContentLength.Value.ToString(UsCulture);
             }
-            
+
             if (isHeadRequest)
             {
                 using (response)
@@ -324,7 +326,7 @@ namespace MediaBrowser.Api.Playback.Progressive
             {
                 TranscodingJob job;
 
-				if (!FileSystem.FileExists(outputPath))
+                if (!FileSystem.FileExists(outputPath))
                 {
                     job = await StartFfMpeg(state, outputPath, cancellationTokenSource).ConfigureAwait(false);
                 }

+ 3 - 2
MediaBrowser.Api/Playback/Progressive/VideoService.cs

@@ -10,6 +10,7 @@ using MediaBrowser.Model.Serialization;
 using ServiceStack;
 using System;
 using System.IO;
+using System.Threading.Tasks;
 using CommonIO;
 using MediaBrowser.Model.Dlna;
 
@@ -76,7 +77,7 @@ namespace MediaBrowser.Api.Playback.Progressive
         /// </summary>
         /// <param name="request">The request.</param>
         /// <returns>System.Object.</returns>
-        public object Get(GetVideoStream request)
+        public Task<object> Get(GetVideoStream request)
         {
             return ProcessRequest(request, false);
         }
@@ -86,7 +87,7 @@ namespace MediaBrowser.Api.Playback.Progressive
         /// </summary>
         /// <param name="request">The request.</param>
         /// <returns>System.Object.</returns>
-        public object Head(GetVideoStream request)
+        public Task<object> Head(GetVideoStream request)
         {
             return ProcessRequest(request, true);
         }

+ 2 - 2
MediaBrowser.Api/PlaylistService.cs

@@ -157,7 +157,7 @@ namespace MediaBrowser.Api
             Task.WaitAll(task);
         }
 
-        public object Get(GetPlaylistItems request)
+        public async Task<object> Get(GetPlaylistItems request)
         {
             var playlist = (Playlist)_libraryManager.GetItemById(request.Id);
             var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null;
@@ -178,7 +178,7 @@ namespace MediaBrowser.Api
 
             var dtoOptions = GetDtoOptions(request);
 
-            var dtos = _dtoService.GetBaseItemDtos(items.Select(i => i.Item2), dtoOptions, user)
+            var dtos = (await _dtoService.GetBaseItemDtos(items.Select(i => i.Item2), dtoOptions, user).ConfigureAwait(false))
                    .ToArray();
 
             var index = 0;

+ 7 - 5
MediaBrowser.Api/SimilarItemsHelper.cs

@@ -9,6 +9,8 @@ using ServiceStack;
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Threading.Tasks;
+using MediaBrowser.Model.Dto;
 
 namespace MediaBrowser.Api
 {
@@ -54,7 +56,7 @@ namespace MediaBrowser.Api
     /// </summary>
     public static class SimilarItemsHelper
     {
-        internal static ItemsResult GetSimilarItemsResult(DtoOptions dtoOptions, IUserManager userManager, IItemRepository itemRepository, ILibraryManager libraryManager, IUserDataManager userDataRepository, IDtoService dtoService, ILogger logger, BaseGetSimilarItemsFromItem request, Type[] includeTypes, Func<BaseItem, List<PersonInfo>, List<PersonInfo>, BaseItem, int> getSimilarityScore)
+        internal static async Task<QueryResult<BaseItemDto>> GetSimilarItemsResult(DtoOptions dtoOptions, IUserManager userManager, IItemRepository itemRepository, ILibraryManager libraryManager, IUserDataManager userDataRepository, IDtoService dtoService, ILogger logger, BaseGetSimilarItemsFromItem request, Type[] includeTypes, Func<BaseItem, List<PersonInfo>, List<PersonInfo>, BaseItem, int> getSimilarityScore)
         {
             var user = !string.IsNullOrWhiteSpace(request.UserId) ? userManager.GetUserById(request.UserId) : null;
 
@@ -80,14 +82,14 @@ namespace MediaBrowser.Api
                 returnItems = returnItems.Take(request.Limit.Value);
             }
 
-            var result = new ItemsResult
+            var dtos = await dtoService.GetBaseItemDtos(returnItems, dtoOptions, user).ConfigureAwait(false);
+
+            return new QueryResult<BaseItemDto>
             {
-                Items = dtoService.GetBaseItemDtos(returnItems, dtoOptions, user).ToArray(),
+                Items = dtos.ToArray(),
 
                 TotalRecordCount = items.Count
             };
-
-            return result;
         }
 
         /// <summary>

+ 5 - 5
MediaBrowser.Api/Subtitles/SubtitleService.cs

@@ -210,7 +210,7 @@ namespace MediaBrowser.Api.Subtitles
                 var subtitleStream = mediaSource.MediaStreams
                     .First(i => i.Type == MediaStreamType.Subtitle && i.Index == request.Index);
 
-                return ToStaticFileResult(subtitleStream.Path);
+                return await ResultFactory.GetStaticFileResult(Request, subtitleStream.Path).ConfigureAwait(false);
             }
 
             using (var stream = await GetSubtitles(request).ConfigureAwait(false))
@@ -229,9 +229,9 @@ namespace MediaBrowser.Api.Subtitles
             }
         }
 
-        private  Task<Stream> GetSubtitles(GetSubtitle request)
+        private Task<Stream> GetSubtitles(GetSubtitle request)
         {
-            return  _subtitleEncoder.GetSubtitles(request.Id,
+            return _subtitleEncoder.GetSubtitles(request.Id,
                 request.MediaSourceId,
                 request.Index,
                 request.Format,
@@ -264,9 +264,9 @@ namespace MediaBrowser.Api.Subtitles
             return ToOptimizedResult(result);
         }
 
-        public object Get(GetRemoteSubtitles request)
+        public async Task<object> Get(GetRemoteSubtitles request)
         {
-            var result = _subtitleManager.GetRemoteSubtitles(request.Id, CancellationToken.None).Result;
+            var result = await _subtitleManager.GetRemoteSubtitles(request.Id, CancellationToken.None).ConfigureAwait(false);
 
             return ResultFactory.GetResult(result.Stream, MimeTypes.GetMimeType("file." + result.Format));
         }

+ 6 - 8
MediaBrowser.Api/Sync/SyncService.cs

@@ -227,7 +227,7 @@ namespace MediaBrowser.Api.Sync
             Task.WaitAll(task);
         }
 
-        public object Get(GetSyncJobItemFile request)
+        public async Task<object> Get(GetSyncJobItemFile request)
         {
             var jobItem = _syncManager.GetJobItem(request.Id);
 
@@ -241,8 +241,7 @@ namespace MediaBrowser.Api.Sync
                 throw new ArgumentException("The job item is not yet ready for transfer.");
             }
 
-            var task = _syncManager.ReportSyncJobItemTransferBeginning(request.Id);
-            Task.WaitAll(task);
+            await _syncManager.ReportSyncJobItemTransferBeginning(request.Id).ConfigureAwait(false);
 
             return ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
             {
@@ -255,7 +254,7 @@ namespace MediaBrowser.Api.Sync
             });
         }
 
-        public object Get(GetSyncDialogOptions request)
+        public async Task<object> Get(GetSyncDialogOptions request)
         {
             var result = new SyncDialogOptions();
 
@@ -298,8 +297,7 @@ namespace MediaBrowser.Api.Sync
                     .Select(_libraryManager.GetItemById)
                     .Where(i => i != null);
 
-                var dtos = _dtoService.GetBaseItemDtos(items, dtoOptions, authenticatedUser)
-                    .ToList();
+                var dtos = (await _dtoService.GetBaseItemDtos(items, dtoOptions, authenticatedUser).ConfigureAwait(false));
 
                 result.Options = SyncHelper.GetSyncOptions(dtos);
             }
@@ -343,7 +341,7 @@ namespace MediaBrowser.Api.Sync
             Task.WaitAll(task);
         }
 
-        public object Get(GetSyncJobItemAdditionalFile request)
+        public Task<object> Get(GetSyncJobItemAdditionalFile request)
         {
             var jobItem = _syncManager.GetJobItem(request.Id);
 
@@ -359,7 +357,7 @@ namespace MediaBrowser.Api.Sync
                 throw new ArgumentException("Sync job additional file not found.");
             }
 
-            return ToStaticFileResult(file.Path);
+            return ResultFactory.GetStaticFileResult(Request, file.Path);
         }
 
         public void Post(EnableSyncJobItem request)

+ 1 - 1
MediaBrowser.Api/System/SystemService.cs

@@ -144,7 +144,7 @@ namespace MediaBrowser.Api.System
             return ToOptimizedResult(result);
         }
 
-        public object Get(GetLogFile request)
+        public Task<object> Get(GetLogFile request)
         {
 			var file = _fileSystem.GetFiles(_appPaths.LogDirectoryPath)
                 .First(i => string.Equals(i.Name, request.Name, StringComparison.OrdinalIgnoreCase));

+ 13 - 12
MediaBrowser.Api/TvShowsService.cs

@@ -12,6 +12,7 @@ using ServiceStack;
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Threading.Tasks;
 using MediaBrowser.Model.Dto;
 
 namespace MediaBrowser.Api
@@ -272,14 +273,14 @@ namespace MediaBrowser.Api
         /// </summary>
         /// <param name="request">The request.</param>
         /// <returns>System.Object.</returns>
-        public object Get(GetSimilarShows request)
+        public async Task<object> Get(GetSimilarShows request)
         {
-            var result = GetSimilarItemsResult(request);
+            var result = await GetSimilarItemsResult(request).ConfigureAwait(false);
 
             return ToOptimizedSerializedResultUsingCache(result);
         }
 
-        private QueryResult<BaseItemDto> GetSimilarItemsResult(BaseGetSimilarItemsFromItem request)
+        private async Task<QueryResult<BaseItemDto>> GetSimilarItemsResult(BaseGetSimilarItemsFromItem request)
         {
             var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null;
 
@@ -302,7 +303,7 @@ namespace MediaBrowser.Api
 
             var result = new QueryResult<BaseItemDto>
             {
-                Items = _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ToArray(),
+                Items = (await _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ConfigureAwait(false)).ToArray(),
 
                 TotalRecordCount = itemsResult.Count
             };
@@ -310,7 +311,7 @@ namespace MediaBrowser.Api
             return result;
         }
 
-        public object Get(GetUpcomingEpisodes request)
+        public async Task<object> Get(GetUpcomingEpisodes request)
         {
             var user = _userManager.GetUserById(request.UserId);
 
@@ -331,7 +332,7 @@ namespace MediaBrowser.Api
 
             var options = GetDtoOptions(request);
 
-            var returnItems = _dtoService.GetBaseItemDtos(itemsResult, options, user).ToArray();
+            var returnItems = (await _dtoService.GetBaseItemDtos(itemsResult, options, user).ConfigureAwait(false)).ToArray();
 
             var result = new ItemsResult
             {
@@ -347,7 +348,7 @@ namespace MediaBrowser.Api
         /// </summary>
         /// <param name="request">The request.</param>
         /// <returns>System.Object.</returns>
-        public object Get(GetNextUpEpisodes request)
+        public async Task<object> Get(GetNextUpEpisodes request)
         {
             var result = _tvSeriesManager.GetNextUp(new NextUpQuery
             {
@@ -362,7 +363,7 @@ namespace MediaBrowser.Api
 
             var options = GetDtoOptions(request);
 
-            var returnItems = _dtoService.GetBaseItemDtos(result.Items, options, user).ToArray();
+            var returnItems = (await _dtoService.GetBaseItemDtos(result.Items, options, user).ConfigureAwait(false)).ToArray();
 
             return ToOptimizedSerializedResultUsingCache(new ItemsResult
             {
@@ -395,7 +396,7 @@ namespace MediaBrowser.Api
             return items;
         }
 
-        public object Get(GetSeasons request)
+        public async Task<object> Get(GetSeasons request)
         {
             var user = _userManager.GetUserById(request.UserId);
 
@@ -426,7 +427,7 @@ namespace MediaBrowser.Api
 
             var dtoOptions = GetDtoOptions(request);
 
-            var returnItems = _dtoService.GetBaseItemDtos(seasons, dtoOptions, user)
+            var returnItems = (await _dtoService.GetBaseItemDtos(seasons, dtoOptions, user).ConfigureAwait(false))
                 .ToArray();
 
             return new ItemsResult
@@ -453,7 +454,7 @@ namespace MediaBrowser.Api
             return items;
         }
 
-        public object Get(GetEpisodes request)
+        public async Task<object> Get(GetEpisodes request)
         {
             var user = _userManager.GetUserById(request.UserId);
 
@@ -535,7 +536,7 @@ namespace MediaBrowser.Api
 
             var dtoOptions = GetDtoOptions(request);
 
-            var dtos = _dtoService.GetBaseItemDtos(pagedItems, dtoOptions, user)
+            var dtos = (await _dtoService.GetBaseItemDtos(pagedItems, dtoOptions, user).ConfigureAwait(false))
                 .ToArray();
 
             return new ItemsResult

+ 1 - 1
MediaBrowser.Api/UserLibrary/ItemsService.cs

@@ -92,7 +92,7 @@ namespace MediaBrowser.Api.UserLibrary
             return new ItemsResult
             {
                 TotalRecordCount = result.TotalRecordCount,
-                Items = _dtoService.GetBaseItemDtos(result.Items, dtoOptions, user).ToArray()
+                Items = (await _dtoService.GetBaseItemDtos(result.Items, dtoOptions, user).ConfigureAwait(false)).ToArray()
             };
         }
 

+ 3 - 3
MediaBrowser.Api/UserLibrary/PlaystateService.cs

@@ -247,9 +247,9 @@ namespace MediaBrowser.Api.UserLibrary
         /// Posts the specified request.
         /// </summary>
         /// <param name="request">The request.</param>
-        public object Post(MarkPlayedItem request)
+        public async Task<object> Post(MarkPlayedItem request)
         {
-            var result = MarkPlayed(request).Result;
+            var result = await MarkPlayed(request).ConfigureAwait(false);
 
             return ToOptimizedResult(result);
         }
@@ -429,7 +429,7 @@ namespace MediaBrowser.Api.UserLibrary
                 await item.MarkUnplayed(user).ConfigureAwait(false);
             }
 
-            return _userDataRepository.GetUserDataDto(item, user);
+            return await _userDataRepository.GetUserDataDto(item, user).ConfigureAwait(false);
         }
     }
 }

+ 6 - 6
MediaBrowser.Api/UserLibrary/UserLibraryService.cs

@@ -488,9 +488,9 @@ namespace MediaBrowser.Api.UserLibrary
         /// Posts the specified request.
         /// </summary>
         /// <param name="request">The request.</param>
-        public object Post(MarkFavoriteItem request)
+        public async Task<object> Post(MarkFavoriteItem request)
         {
-            var dto = MarkFavorite(request.UserId, request.Id, true).Result;
+            var dto = await MarkFavorite(request.UserId, request.Id, true).ConfigureAwait(false);
 
             return ToOptimizedResult(dto);
         }
@@ -527,7 +527,7 @@ namespace MediaBrowser.Api.UserLibrary
 
             await _userDataRepository.SaveUserData(user.Id, item, data, UserDataSaveReason.UpdateUserRating, CancellationToken.None).ConfigureAwait(false);
 
-            return _userDataRepository.GetUserDataDto(item, user);
+            return await _userDataRepository.GetUserDataDto(item, user).ConfigureAwait(false);
         }
 
         /// <summary>
@@ -545,9 +545,9 @@ namespace MediaBrowser.Api.UserLibrary
         /// Posts the specified request.
         /// </summary>
         /// <param name="request">The request.</param>
-        public object Post(UpdateUserItemRating request)
+        public async Task<object> Post(UpdateUserItemRating request)
         {
-            var dto = UpdateUserItemRating(request.UserId, request.Id, request.Likes).Result;
+            var dto = await UpdateUserItemRating(request.UserId, request.Id, request.Likes).ConfigureAwait(false);
 
             return ToOptimizedResult(dto);
         }
@@ -572,7 +572,7 @@ namespace MediaBrowser.Api.UserLibrary
 
             await _userDataRepository.SaveUserData(user.Id, item, data, UserDataSaveReason.UpdateUserRating, CancellationToken.None).ConfigureAwait(false);
 
-            return _userDataRepository.GetUserDataDto(item, user);
+            return await _userDataRepository.GetUserDataDto(item, user).ConfigureAwait(false);
         }
     }
 }

+ 2 - 1
MediaBrowser.Controller/Dto/IDtoService.cs

@@ -3,6 +3,7 @@ using MediaBrowser.Controller.Entities;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Querying;
 using System.Collections.Generic;
+using System.Threading.Tasks;
 
 namespace MediaBrowser.Controller.Dto
 {
@@ -68,7 +69,7 @@ namespace MediaBrowser.Controller.Dto
         /// <param name="user">The user.</param>
         /// <param name="owner">The owner.</param>
         /// <returns>IEnumerable&lt;BaseItemDto&gt;.</returns>
-        IEnumerable<BaseItemDto> GetBaseItemDtos(IEnumerable<BaseItem> items, DtoOptions options, User user = null,
+        Task<List<BaseItemDto>> GetBaseItemDtos(IEnumerable<BaseItem> items, DtoOptions options, User user = null,
             BaseItem owner = null);
         
         /// <summary>

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

@@ -2093,7 +2093,7 @@ namespace MediaBrowser.Controller.Entities
             return path;
         }
 
-        public virtual void FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, User user)
+        public virtual Task FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user)
         {
             if (RunTimeTicks.HasValue)
             {
@@ -2109,6 +2109,8 @@ namespace MediaBrowser.Controller.Entities
                     }
                 }
             }
+
+            return Task.FromResult(true);
         }
 
         protected Task RefreshMetadataForOwnedVideo(MetadataRefreshOptions options, string path, CancellationToken cancellationToken)

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

@@ -13,6 +13,7 @@ using System.Runtime.Serialization;
 using System.Threading;
 using System.Threading.Tasks;
 using CommonIO;
+using MediaBrowser.Controller.Channels;
 using MediaBrowser.Model.Channels;
 
 namespace MediaBrowser.Controller.Entities
@@ -1422,19 +1423,27 @@ namespace MediaBrowser.Controller.Entities
                 {
                     return false;
                 }
+                if (this is Channel)
+                {
+                    return false;
+                }
+                if (SourceType != SourceType.Library)
+                {
+                    return false;
+                }
 
                 return true;
             }
         }
 
-        public override void FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, User user)
+        public override async Task FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user)
         {
             if (!SupportsUserDataFromChildren)
             {
                 return;
             }
 
-            var unplayedQueryResult = GetItems(new InternalItemsQuery(user)
+            var unplayedQueryResult = await GetItems(new InternalItemsQuery(user)
             {
                 Recursive = true,
                 IsFolder = false,
@@ -1443,9 +1452,9 @@ namespace MediaBrowser.Controller.Entities
                 Limit = 0,
                 IsPlayed = false
 
-            }).Result;
+            }).ConfigureAwait(false);
 
-            var allItemsQueryResult = GetItems(new InternalItemsQuery(user)
+            var allItemsQueryResult = await GetItems(new InternalItemsQuery(user)
             {
                 Recursive = true,
                 IsFolder = false,
@@ -1453,7 +1462,12 @@ namespace MediaBrowser.Controller.Entities
                 EnableTotalRecordCount = true,
                 Limit = 0
 
-            }).Result;
+            }).ConfigureAwait(false);
+
+            if (itemDto != null)
+            {
+                itemDto.RecursiveItemCount = allItemsQueryResult.TotalRecordCount;
+            }
 
             double recursiveItemCount = allItemsQueryResult.TotalRecordCount;
             double unplayedCount = unplayedQueryResult.TotalRecordCount;

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

@@ -1,4 +1,5 @@
 using System.Collections.Generic;
+using System.Threading.Tasks;
 using MediaBrowser.Model.Dto;
 
 namespace MediaBrowser.Controller.Entities
@@ -16,7 +17,7 @@ namespace MediaBrowser.Controller.Entities
         /// <param name="dto">The dto.</param>
         /// <param name="userData">The user data.</param>
         /// <param name="user">The user.</param>
-        void FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, User user);
+        Task FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user);
 
         bool EnableRememberingTrackSelections { get; }
     }

+ 3 - 2
MediaBrowser.Controller/IServerApplicationHost.cs

@@ -3,6 +3,7 @@ using MediaBrowser.Model.System;
 using System;
 using System.Collections.Generic;
 using System.Net;
+using System.Threading.Tasks;
 
 namespace MediaBrowser.Controller
 {
@@ -65,13 +66,13 @@ namespace MediaBrowser.Controller
         /// Gets the local ip address.
         /// </summary>
         /// <value>The local ip address.</value>
-        List<IPAddress> LocalIpAddresses { get; }
+        Task<List<IPAddress>> GetLocalIpAddresses();
 
         /// <summary>
         /// Gets the local API URL.
         /// </summary>
         /// <value>The local API URL.</value>
-        string LocalApiUrl { get; }
+        Task<string> GetLocalApiUrl();
 
         /// <summary>
         /// Gets the local API URL.

+ 3 - 1
MediaBrowser.Controller/Library/IUserDataManager.cs

@@ -40,7 +40,9 @@ namespace MediaBrowser.Controller.Library
         /// <param name="item">The item.</param>
         /// <param name="user">The user.</param>
         /// <returns>UserItemDataDto.</returns>
-        UserItemDataDto GetUserDataDto(IHasUserData item, User user);
+        Task<UserItemDataDto> GetUserDataDto(IHasUserData item, User user);
+
+        Task<UserItemDataDto> GetUserDataDto(IHasUserData item, BaseItemDto itemDto, User user);
 
         /// <summary>
         /// Get all user data for the given user

+ 4 - 4
MediaBrowser.Controller/Net/IHttpResultFactory.cs

@@ -80,7 +80,7 @@ namespace MediaBrowser.Controller.Net
         /// <param name="responseHeaders">The response headers.</param>
         /// <param name="isHeadRequest">if set to <c>true</c> [is head request].</param>
         /// <returns>System.Object.</returns>
-        object GetStaticResult(IRequest requestContext, 
+        Task<object> GetStaticResult(IRequest requestContext, 
             Guid cacheKey, 
             DateTime? lastDateModified,
             TimeSpan? cacheDuration, 
@@ -94,7 +94,7 @@ namespace MediaBrowser.Controller.Net
         /// <param name="requestContext">The request context.</param>
         /// <param name="options">The options.</param>
         /// <returns>System.Object.</returns>
-        object GetStaticResult(IRequest requestContext, StaticResultOptions options);
+        Task<object> GetStaticResult(IRequest requestContext, StaticResultOptions options);
 
         /// <summary>
         /// Gets the static file result.
@@ -103,7 +103,7 @@ namespace MediaBrowser.Controller.Net
         /// <param name="path">The path.</param>
         /// <param name="fileShare">The file share.</param>
         /// <returns>System.Object.</returns>
-        object GetStaticFileResult(IRequest requestContext, string path, FileShare fileShare = FileShare.Read);
+        Task<object> GetStaticFileResult(IRequest requestContext, string path, FileShare fileShare = FileShare.Read);
 
         /// <summary>
         /// Gets the static file result.
@@ -111,7 +111,7 @@ namespace MediaBrowser.Controller.Net
         /// <param name="requestContext">The request context.</param>
         /// <param name="options">The options.</param>
         /// <returns>System.Object.</returns>
-        object GetStaticFileResult(IRequest requestContext, 
+        Task<object> GetStaticFileResult(IRequest requestContext, 
             StaticFileResultOptions options);
     }
 }

+ 2 - 2
MediaBrowser.Dlna/Didl/DidlBuilder.cs

@@ -846,7 +846,7 @@ namespace MediaBrowser.Dlna.Didl
 
             if (item is Video)
             {
-                var userData = _userDataManager.GetUserDataDto(item, _user);
+                var userData = _userDataManager.GetUserDataDto(item, _user).Result;
 
                 playbackPercentage = Convert.ToInt32(userData.PlayedPercentage ?? 0);
                 if (playbackPercentage >= 100 || userData.Played)
@@ -856,7 +856,7 @@ namespace MediaBrowser.Dlna.Didl
             }
             else if (item is Series || item is Season || item is BoxSet)
             {
-                var userData = _userDataManager.GetUserDataDto(item, _user);
+                var userData = _userDataManager.GetUserDataDto(item, _user).Result;
 
                 if (userData.Played)
                 {

+ 7 - 6
MediaBrowser.Dlna/Main/DlnaEntryPoint.cs

@@ -15,6 +15,7 @@ using MediaBrowser.Model.Logging;
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Threading.Tasks;
 using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Dlna.Channels;
 
@@ -105,7 +106,7 @@ namespace MediaBrowser.Dlna.Main
             }
         }
 
-        private void ReloadComponents()
+        private async void ReloadComponents()
         {
             var options = _config.GetDlnaConfiguration();
 
@@ -130,7 +131,7 @@ namespace MediaBrowser.Dlna.Main
 
             if (options.EnableServer && !isServerStarted)
             {
-                StartDlnaServer();
+                await StartDlnaServer().ConfigureAwait(false);
             }
             else if (!options.EnableServer && isServerStarted)
             {
@@ -208,11 +209,11 @@ namespace MediaBrowser.Dlna.Main
             }
         }
 
-        public void StartDlnaServer()
+        public async Task StartDlnaServer()
         {
             try
             {
-                RegisterServerEndpoints();
+                await RegisterServerEndpoints().ConfigureAwait(false);
 
                 _dlnaServerStarted = true;
             }
@@ -222,9 +223,9 @@ namespace MediaBrowser.Dlna.Main
             }
         }
 
-        private void RegisterServerEndpoints()
+        private async Task RegisterServerEndpoints()
         {
-            foreach (var address in _appHost.LocalIpAddresses)
+            foreach (var address in await _appHost.GetLocalIpAddresses().ConfigureAwait(false))
             {
                 //if (IPAddress.IsLoopback(address))
                 //{

+ 17 - 18
MediaBrowser.Dlna/PlayTo/PlayToController.cs

@@ -62,7 +62,7 @@ namespace MediaBrowser.Dlna.PlayTo
                     }
                     return false;
                 }
-               
+
                 return _device != null;
             }
         }
@@ -119,7 +119,7 @@ namespace MediaBrowser.Dlna.PlayTo
             string nt;
             if (!e.Headers.TryGetValue("NT", out nt)) nt = String.Empty;
 
-            if ( usn.IndexOf(_device.Properties.UUID, StringComparison.OrdinalIgnoreCase) != -1 &&
+            if (usn.IndexOf(_device.Properties.UUID, StringComparison.OrdinalIgnoreCase) != -1 &&
                 !_disposed)
             {
                 if (usn.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) != -1 ||
@@ -141,7 +141,7 @@ namespace MediaBrowser.Dlna.PlayTo
         {
             try
             {
-                var streamInfo = StreamParams.ParseFromUrl(e.OldMediaInfo.Url, _libraryManager, _mediaSourceManager);
+                var streamInfo = await StreamParams.ParseFromUrl(e.OldMediaInfo.Url, _libraryManager, _mediaSourceManager).ConfigureAwait(false);
                 if (streamInfo.Item != null)
                 {
                     var progress = GetProgressInfo(e.OldMediaInfo, streamInfo);
@@ -151,9 +151,9 @@ namespace MediaBrowser.Dlna.PlayTo
                     ReportPlaybackStopped(e.OldMediaInfo, streamInfo, positionTicks);
                 }
 
-                streamInfo = StreamParams.ParseFromUrl(e.NewMediaInfo.Url, _libraryManager, _mediaSourceManager);
+                streamInfo = await StreamParams.ParseFromUrl(e.NewMediaInfo.Url, _libraryManager, _mediaSourceManager).ConfigureAwait(false);
                 if (streamInfo.Item == null) return;
-                
+
                 var newItemProgress = GetProgressInfo(e.NewMediaInfo, streamInfo);
 
                 await _sessionManager.OnPlaybackStart(newItemProgress).ConfigureAwait(false);
@@ -168,7 +168,8 @@ namespace MediaBrowser.Dlna.PlayTo
         {
             try
             {
-                var streamInfo = StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager, _mediaSourceManager);
+                var streamInfo = await StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager, _mediaSourceManager)
+                            .ConfigureAwait(false);
 
                 if (streamInfo.Item == null) return;
 
@@ -230,7 +231,7 @@ namespace MediaBrowser.Dlna.PlayTo
         {
             try
             {
-                var info = StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager, _mediaSourceManager);
+                var info = await StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager, _mediaSourceManager).ConfigureAwait(false);
 
                 if (info.Item != null)
                 {
@@ -249,7 +250,7 @@ namespace MediaBrowser.Dlna.PlayTo
         {
             try
             {
-                var info = StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager, _mediaSourceManager);
+                var info = await StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager, _mediaSourceManager).ConfigureAwait(false);
 
                 if (info.Item != null)
                 {
@@ -377,7 +378,7 @@ namespace MediaBrowser.Dlna.PlayTo
 
             if (media != null)
             {
-                var info = StreamParams.ParseFromUrl(media.Url, _libraryManager, _mediaSourceManager);
+                var info = await StreamParams.ParseFromUrl(media.Url, _libraryManager, _mediaSourceManager).ConfigureAwait(false);
 
                 if (info.Item != null && !EnableClientSideSeek(info))
                 {
@@ -470,7 +471,7 @@ namespace MediaBrowser.Dlna.PlayTo
 
             var profile = _dlnaManager.GetProfile(deviceInfo.ToDeviceIdentification()) ??
                 _dlnaManager.GetDefaultProfile();
-            
+
             var hasMediaSources = item as IHasMediaSources;
             var mediaSources = hasMediaSources != null
                 ? (_mediaSourceManager.GetStaticMediaSources(hasMediaSources, true, user)).ToList()
@@ -739,7 +740,7 @@ namespace MediaBrowser.Dlna.PlayTo
 
             if (media != null)
             {
-                var info = StreamParams.ParseFromUrl(media.Url, _libraryManager, _mediaSourceManager);
+                var info = await StreamParams.ParseFromUrl(media.Url, _libraryManager, _mediaSourceManager).ConfigureAwait(false);
 
                 if (info.Item != null)
                 {
@@ -765,7 +766,7 @@ namespace MediaBrowser.Dlna.PlayTo
 
             if (media != null)
             {
-                var info = StreamParams.ParseFromUrl(media.Url, _libraryManager, _mediaSourceManager);
+                var info = await StreamParams.ParseFromUrl(media.Url, _libraryManager, _mediaSourceManager).ConfigureAwait(false);
 
                 if (info.Item != null)
                 {
@@ -840,7 +841,7 @@ namespace MediaBrowser.Dlna.PlayTo
                 return null;
             }
 
-            public static StreamParams ParseFromUrl(string url, ILibraryManager libraryManager, IMediaSourceManager mediaSourceManager)
+            public static async Task<StreamParams> ParseFromUrl(string url, ILibraryManager libraryManager, IMediaSourceManager mediaSourceManager)
             {
                 var request = new StreamParams
                 {
@@ -906,11 +907,9 @@ namespace MediaBrowser.Dlna.PlayTo
 
                 var hasMediaSources = request.Item as IHasMediaSources;
 
-                request.MediaSource = hasMediaSources == null ?
-                    null :
-                    mediaSourceManager.GetMediaSource(hasMediaSources, request.MediaSourceId, false).Result;
-
-
+                request.MediaSource = hasMediaSources == null
+                    ? null
+                    : (await mediaSourceManager.GetMediaSource(hasMediaSources, request.MediaSourceId, false).ConfigureAwait(false));
 
                 return request;
             }

+ 2 - 2
MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs

@@ -61,7 +61,7 @@ namespace MediaBrowser.Dlna.Ssdp
 			}
         }
 
-        void _ssdpHandler_MessageReceived(object sender, SsdpMessageEventArgs e)
+        async void _ssdpHandler_MessageReceived(object sender, SsdpMessageEventArgs e)
         {
             string nts;
             e.Headers.TryGetValue("NTS", out nts);
@@ -78,7 +78,7 @@ namespace MediaBrowser.Dlna.Ssdp
             {
                 if (e.LocalEndPoint == null)
                 {
-                    var ip = _appHost.LocalIpAddresses.FirstOrDefault(i => !IPAddress.IsLoopback(i));
+                    var ip = (await _appHost.GetLocalIpAddresses().ConfigureAwait(false)).FirstOrDefault(i => !IPAddress.IsLoopback(i));
                     if (ip != null)
                     {
                         e.LocalEndPoint = new IPEndPoint(ip, 0);

+ 5 - 2
MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs

@@ -6,6 +6,7 @@ using MediaBrowser.Model.IO;
 using MediaBrowser.Model.Logging;
 using System;
 using System.Collections.Generic;
+using System.Threading.Tasks;
 using CommonIO;
 
 namespace MediaBrowser.MediaEncoding.Encoder
@@ -16,7 +17,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
         {
         }
 
-        protected override string GetCommandLineArguments(EncodingJob state)
+        protected override Task<string> GetCommandLineArguments(EncodingJob state)
         {
             var audioTranscodeParams = new List<string>();
 
@@ -61,7 +62,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
                 vn = " -vn";
             }
 
-            return string.Format("{0} {1}{6}{7} -threads {2}{3} {4} -id3v2_version 3 -write_id3v1 1{8} -y \"{5}\"",
+            var result = string.Format("{0} {1}{6}{7} -threads {2}{3} {4} -id3v2_version 3 -write_id3v1 1{8} -y \"{5}\"",
                 inputModifier,
                 GetInputArgument(state),
                 threads,
@@ -71,6 +72,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
                 albumCoverInput,
                 mapArgs,
                 metadata).Trim();
+
+            return Task.FromResult(result);
         }
 
         protected override string GetOutputFileExtension(EncodingJob state)

+ 15 - 14
MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs

@@ -42,8 +42,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
             IFileSystem fileSystem,
             IIsoManager isoManager,
             ILibraryManager libraryManager,
-            ISessionManager sessionManager, 
-            ISubtitleEncoder subtitleEncoder, 
+            ISessionManager sessionManager,
+            ISubtitleEncoder subtitleEncoder,
             IMediaSourceManager mediaSourceManager)
         {
             MediaEncoder = mediaEncoder;
@@ -71,7 +71,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
 
             await AcquireResources(encodingJob, cancellationToken).ConfigureAwait(false);
 
-            var commandLineArgs = GetCommandLineArguments(encodingJob);
+            var commandLineArgs = await GetCommandLineArguments(encodingJob).ConfigureAwait(false);
 
             var process = new Process
             {
@@ -131,7 +131,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
             }
 
             cancellationToken.Register(() => Cancel(process, encodingJob));
-            
+
             // MUST read both stdout and stderr asynchronously or a deadlock may occurr
             process.BeginOutputReadLine();
 
@@ -139,7 +139,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
             new JobLogger(Logger).StartStreamingLog(encodingJob, process.StandardError.BaseStream, encodingJob.LogFileStream);
 
             // Wait for the file to exist before proceeeding
-			while (!FileSystem.FileExists(encodingJob.OutputFilePath) && !encodingJob.HasExited)
+            while (!FileSystem.FileExists(encodingJob.OutputFilePath) && !encodingJob.HasExited)
             {
                 await Task.Delay(100, cancellationToken).ConfigureAwait(false);
             }
@@ -264,11 +264,11 @@ namespace MediaBrowser.MediaEncoding.Encoder
             return ConfigurationManager.GetConfiguration<EncodingOptions>("encoding");
         }
 
-        protected abstract string GetCommandLineArguments(EncodingJob job);
+        protected abstract Task<string> GetCommandLineArguments(EncodingJob job);
 
         private string GetOutputFilePath(EncodingJob state)
         {
-            var folder = string.IsNullOrWhiteSpace(state.Options.OutputDirectory) ? 
+            var folder = string.IsNullOrWhiteSpace(state.Options.OutputDirectory) ?
                 ConfigurationManager.ApplicationPaths.TranscodingTempPath :
                 state.Options.OutputDirectory;
 
@@ -363,7 +363,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
         {
             if (string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase))
             {
-                return null;    
+                return null;
             }
 
             if (state.VideoStream != null && !string.IsNullOrWhiteSpace(state.VideoStream.Codec))
@@ -536,7 +536,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
         /// <param name="state">The state.</param>
         /// <param name="outputVideoCodec">The output video codec.</param>
         /// <returns>System.String.</returns>
-        protected string GetGraphicalSubtitleParam(EncodingJob state, string outputVideoCodec)
+        protected async Task<string> GetGraphicalSubtitleParam(EncodingJob state, string outputVideoCodec)
         {
             var outputSizeParam = string.Empty;
 
@@ -545,7 +545,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
             // Add resolution params, if specified
             if (request.Width.HasValue || request.Height.HasValue || request.MaxHeight.HasValue || request.MaxWidth.HasValue)
             {
-                outputSizeParam = GetOutputSizeParam(state, outputVideoCodec).TrimEnd('"');
+                outputSizeParam = await GetOutputSizeParam(state, outputVideoCodec).ConfigureAwait(false);
+                outputSizeParam = outputSizeParam.TrimEnd('"');
                 outputSizeParam = "," + outputSizeParam.Substring(outputSizeParam.IndexOf("scale", StringComparison.OrdinalIgnoreCase));
             }
 
@@ -858,7 +859,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
         /// <param name="outputVideoCodec">The output video codec.</param>
         /// <param name="allowTimeStampCopy">if set to <c>true</c> [allow time stamp copy].</param>
         /// <returns>System.String.</returns>
-        protected string GetOutputSizeParam(EncodingJob state,
+        protected async Task<string> GetOutputSizeParam(EncodingJob state,
             string outputVideoCodec,
             bool allowTimeStampCopy = true)
         {
@@ -935,7 +936,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
 
             if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.Options.SubtitleMethod == SubtitleDeliveryMethod.Encode)
             {
-                var subParam = GetTextSubtitleParam(state);
+                var subParam = await GetTextSubtitleParam(state).ConfigureAwait(false);
 
                 filters.Add(subParam);
 
@@ -958,7 +959,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
         /// </summary>
         /// <param name="state">The state.</param>
         /// <returns>System.String.</returns>
-        protected string GetTextSubtitleParam(EncodingJob state)
+        protected async Task<string> GetTextSubtitleParam(EncodingJob state)
         {
             var seconds = Math.Round(TimeSpan.FromTicks(state.Options.StartTimeTicks ?? 0).TotalSeconds);
 
@@ -970,7 +971,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
 
                 if (!string.IsNullOrEmpty(state.SubtitleStream.Language))
                 {
-                    var charenc = SubtitleEncoder.GetSubtitleFileCharacterSet(subtitlePath, state.SubtitleStream.Language, state.MediaSource.Protocol, CancellationToken.None).Result;
+                    var charenc = await SubtitleEncoder.GetSubtitleFileCharacterSet(subtitlePath, state.SubtitleStream.Language, state.MediaSource.Protocol, CancellationToken.None).ConfigureAwait(false);
 
                     if (!string.IsNullOrEmpty(charenc))
                     {

+ 7 - 4
MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs

@@ -7,6 +7,7 @@ using MediaBrowser.Model.IO;
 using MediaBrowser.Model.Logging;
 using System;
 using System.IO;
+using System.Threading.Tasks;
 using CommonIO;
 
 namespace MediaBrowser.MediaEncoding.Encoder
@@ -17,7 +18,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
         {
         }
 
-        protected override string GetCommandLineArguments(EncodingJob state)
+        protected override async Task<string> GetCommandLineArguments(EncodingJob state)
         {
             // Get the output codec name
             var videoCodec = EncodingJobFactory.GetVideoEncoder(state, GetEncodingOptions());
@@ -36,12 +37,14 @@ namespace MediaBrowser.MediaEncoding.Encoder
 
             var inputModifier = GetInputModifier(state);
 
+            var videoArguments = await GetVideoArguments(state, videoCodec).ConfigureAwait(false);
+
             return string.Format("{0} {1}{2} {3} {4} -map_metadata -1 -threads {5} {6}{7} -y \"{8}\"",
                 inputModifier,
                 GetInputArgument(state),
                 keyFrame,
                 GetMapArgs(state),
-                GetVideoArguments(state, videoCodec),
+                videoArguments,
                 threads,
                 GetAudioArguments(state),
                 format,
@@ -55,7 +58,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
         /// <param name="state">The state.</param>
         /// <param name="videoCodec">The video codec.</param>
         /// <returns>System.String.</returns>
-        private string GetVideoArguments(EncodingJob state, string videoCodec)
+        private async Task<string> GetVideoArguments(EncodingJob state, string videoCodec)
         {
             var args = "-codec:v:0 " + videoCodec;
 
@@ -104,7 +107,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
             // This is for internal graphical subs
             if (hasGraphicalSubs)
             {
-                args += GetGraphicalSubtitleParam(state, videoCodec);
+                args += await GetGraphicalSubtitleParam(state, videoCodec).ConfigureAwait(false);
             }
 
             return args;

+ 4 - 4
MediaBrowser.Server.Implementations/Channels/ChannelManager.cs

@@ -191,7 +191,7 @@ namespace MediaBrowser.Server.Implementations.Channels
 
             var dtoOptions = new DtoOptions();
 
-            var returnItems = _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user)
+            var returnItems = (await _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user).ConfigureAwait(false))
                 .ToArray();
 
             var result = new QueryResult<BaseItemDto>
@@ -596,7 +596,7 @@ namespace MediaBrowser.Server.Implementations.Channels
 
             var dtoOptions = new DtoOptions();
 
-            var returnItems = _dtoService.GetBaseItemDtos(items, dtoOptions, user)
+            var returnItems = (await _dtoService.GetBaseItemDtos(items, dtoOptions, user).ConfigureAwait(false))
                 .ToArray();
 
             var result = new QueryResult<BaseItemDto>
@@ -863,7 +863,7 @@ namespace MediaBrowser.Server.Implementations.Channels
 
             var dtoOptions = new DtoOptions();
 
-            var returnItems = _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user)
+            var returnItems = (await _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user).ConfigureAwait(false))
                 .ToArray();
 
             var result = new QueryResult<BaseItemDto>
@@ -1012,7 +1012,7 @@ namespace MediaBrowser.Server.Implementations.Channels
 
             var dtoOptions = new DtoOptions();
 
-            var returnItems = _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user)
+            var returnItems = (await _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user).ConfigureAwait(false))
                 .ToArray();
 
             var result = new QueryResult<BaseItemDto>

+ 8 - 6
MediaBrowser.Server.Implementations/Connect/ConnectManager.cs

@@ -177,7 +177,7 @@ namespace MediaBrowser.Server.Implementations.Connect
 
             try
             {
-                var localAddress = _appHost.LocalApiUrl;
+                var localAddress = await _appHost.GetLocalApiUrl().ConfigureAwait(false);
 
                 var hasExistingRecord = !string.IsNullOrWhiteSpace(ConnectServerId) &&
                                   !string.IsNullOrWhiteSpace(ConnectAccessKey);
@@ -217,24 +217,26 @@ namespace MediaBrowser.Server.Implementations.Connect
         }
 
         private string _lastReportedIdentifier;
-        private string GetConnectReportingIdentifier()
+        private async Task<string> GetConnectReportingIdentifier()
         {
-            return GetConnectReportingIdentifier(_appHost.LocalApiUrl, WanApiAddress);
+            var url = await _appHost.GetLocalApiUrl().ConfigureAwait(false);
+            return GetConnectReportingIdentifier(url, WanApiAddress);
         }
         private string GetConnectReportingIdentifier(string localAddress, string remoteAddress)
         {
             return (remoteAddress ?? string.Empty) + (localAddress ?? string.Empty);
         }
 
-        void _config_ConfigurationUpdated(object sender, EventArgs e)
+        async void _config_ConfigurationUpdated(object sender, EventArgs e)
         {
             // If info hasn't changed, don't report anything
-            if (string.Equals(_lastReportedIdentifier, GetConnectReportingIdentifier(), StringComparison.OrdinalIgnoreCase))
+            var connectIdentifier = await GetConnectReportingIdentifier().ConfigureAwait(false);
+            if (string.Equals(_lastReportedIdentifier, connectIdentifier, StringComparison.OrdinalIgnoreCase))
             {
                 return;
             }
 
-            UpdateConnectInfo();
+            await UpdateConnectInfo().ConfigureAwait(false);
         }
 
         private async Task CreateServerRegistration(string wanApiAddress, string localAddress)

+ 43 - 52
MediaBrowser.Server.Implementations/Dto/DtoService.cs

@@ -86,7 +86,7 @@ namespace MediaBrowser.Server.Implementations.Dto
             return GetBaseItemDto(item, options, user, owner);
         }
 
-        public IEnumerable<BaseItemDto> GetBaseItemDtos(IEnumerable<BaseItem> items, DtoOptions options, User user = null, BaseItem owner = null)
+        public async Task<List<BaseItemDto>> GetBaseItemDtos(IEnumerable<BaseItem> items, DtoOptions options, User user = null, BaseItem owner = null)
         {
             var syncJobItems = GetSyncedItemProgress(options);
             var syncDictionary = GetSyncedItemProgressDictionary(syncJobItems);
@@ -97,7 +97,7 @@ namespace MediaBrowser.Server.Implementations.Dto
 
             foreach (var item in items)
             {
-                var dto = GetBaseItemDtoInternal(item, options, syncDictionary, user, owner);
+                var dto = await GetBaseItemDtoInternal(item, options, syncDictionary, user, owner).ConfigureAwait(false);
 
                 var tvChannel = item as LiveTvChannel;
                 if (tvChannel != null)
@@ -131,8 +131,7 @@ namespace MediaBrowser.Server.Implementations.Dto
 
             if (programTuples.Count > 0)
             {
-                var task = _livetvManager().AddInfoToProgramDto(programTuples, options.Fields, user);
-                Task.WaitAll(task);
+                await _livetvManager().AddInfoToProgramDto(programTuples, options.Fields, user).ConfigureAwait(false);
             }
 
             if (channelTuples.Count > 0)
@@ -159,7 +158,7 @@ namespace MediaBrowser.Server.Implementations.Dto
         {
             var syncProgress = GetSyncedItemProgress(options);
 
-            var dto = GetBaseItemDtoInternal(item, options, GetSyncedItemProgressDictionary(syncProgress), user, owner);
+            var dto = GetBaseItemDtoInternal(item, options, GetSyncedItemProgressDictionary(syncProgress), user, owner).Result;
             var tvChannel = item as LiveTvChannel;
             if (tvChannel != null)
             {
@@ -300,7 +299,7 @@ namespace MediaBrowser.Server.Implementations.Dto
             }
         }
 
-        private BaseItemDto GetBaseItemDtoInternal(BaseItem item, DtoOptions options, Dictionary<string, SyncedItemProgress> syncProgress, User user = null, BaseItem owner = null)
+        private async Task<BaseItemDto> GetBaseItemDtoInternal(BaseItem item, DtoOptions options, Dictionary<string, SyncedItemProgress> syncProgress, User user = null, BaseItem owner = null)
         {
             var fields = options.Fields;
 
@@ -349,7 +348,7 @@ namespace MediaBrowser.Server.Implementations.Dto
 
             if (user != null)
             {
-                AttachUserSpecificInfo(dto, item, user, fields, syncProgress);
+                await AttachUserSpecificInfo(dto, item, user, fields, syncProgress).ConfigureAwait(false);
             }
 
             var hasMediaSources = item as IHasMediaSources;
@@ -416,7 +415,7 @@ namespace MediaBrowser.Server.Implementations.Dto
         {
             var syncProgress = GetSyncedItemProgress(options);
 
-            var dto = GetBaseItemDtoInternal(item, options, GetSyncedItemProgressDictionary(syncProgress), user);
+            var dto = GetBaseItemDtoInternal(item, options, GetSyncedItemProgressDictionary(syncProgress), user).Result;
 
             if (taggedItems != null && options.Fields.Contains(ItemFields.ItemCounts))
             {
@@ -465,21 +464,26 @@ namespace MediaBrowser.Server.Implementations.Dto
         /// <param name="user">The user.</param>
         /// <param name="fields">The fields.</param>
         /// <param name="syncProgress">The synchronize progress.</param>
-        private void AttachUserSpecificInfo(BaseItemDto dto, BaseItem item, User user, List<ItemFields> fields, Dictionary<string, SyncedItemProgress> syncProgress)
+        private async Task AttachUserSpecificInfo(BaseItemDto dto, BaseItem item, User user, List<ItemFields> fields, Dictionary<string, SyncedItemProgress> syncProgress)
         {
             if (item.IsFolder)
             {
                 var folder = (Folder)item;
 
-                // Skip the user data manager because we've already looped through the recursive tree and don't want to do it twice
-                // TODO: Improve in future
-                dto.UserData = GetUserItemDataDto(_userDataRepository.GetUserData(user, item));
-
-                if (item.SourceType == SourceType.Library && folder.SupportsUserDataFromChildren)
+                if (item.SourceType == SourceType.Library && folder.SupportsUserDataFromChildren && fields.Contains(ItemFields.SyncInfo))
                 {
-                    SetSpecialCounts(folder, user, dto, fields, syncProgress);
+                    // Skip the user data manager because we've already looped through the recursive tree and don't want to do it twice
+                    // TODO: Improve in future
+                    dto.UserData = GetUserItemDataDto(_userDataRepository.GetUserData(user, item));
 
-                    dto.UserData.Played = dto.UserData.PlayedPercentage.HasValue && dto.UserData.PlayedPercentage.Value >= 100;
+                    await SetSpecialCounts(folder, user, dto, fields, syncProgress).ConfigureAwait(false);
+
+                    dto.UserData.Played = dto.UserData.PlayedPercentage.HasValue &&
+                                          dto.UserData.PlayedPercentage.Value >= 100;
+                }
+                else
+                {
+                    dto.UserData = await _userDataRepository.GetUserDataDto(item, dto, user).ConfigureAwait(false);
                 }
 
                 if (item.SourceType == SourceType.Library)
@@ -500,7 +504,7 @@ namespace MediaBrowser.Server.Implementations.Dto
 
             else
             {
-                dto.UserData = _userDataRepository.GetUserDataDto(item, user);
+                dto.UserData = _userDataRepository.GetUserDataDto(item, user).Result;
             }
 
             dto.PlayAccess = item.GetPlayAccess(user);
@@ -515,7 +519,7 @@ namespace MediaBrowser.Server.Implementations.Dto
 
                     if (season != null)
                     {
-                        dto.SeasonUserData = _userDataRepository.GetUserDataDto(season, user);
+                        dto.SeasonUserData = await _userDataRepository.GetUserDataDto(season, user).ConfigureAwait(false);
                     }
                 }
             }
@@ -1588,32 +1592,25 @@ namespace MediaBrowser.Server.Implementations.Dto
         /// <param name="fields">The fields.</param>
         /// <param name="syncProgress">The synchronize progress.</param>
         /// <returns>Task.</returns>
-        private void SetSpecialCounts(Folder folder, User user, BaseItemDto dto, List<ItemFields> fields, Dictionary<string, SyncedItemProgress> syncProgress)
+        private async Task SetSpecialCounts(Folder folder, User user, BaseItemDto dto, List<ItemFields> fields, Dictionary<string, SyncedItemProgress> syncProgress)
         {
-            var addSyncInfo = fields.Contains(ItemFields.SyncInfo);
-
-            if (!addSyncInfo)
-            {
-                return;
-            }
-
             var recursiveItemCount = 0;
             var unplayed = 0;
 
             double totalPercentPlayed = 0;
             double totalSyncPercent = 0;
 
-            var children = folder.GetItems(new InternalItemsQuery
+            var children = await folder.GetItems(new InternalItemsQuery
             {
                 IsFolder = false,
                 Recursive = true,
-                ExcludeLocationTypes = new[] { LocationType.Virtual },
+                ExcludeLocationTypes = new[] {LocationType.Virtual},
                 User = user
 
-            }).Result.Items;
+            }).ConfigureAwait(false);
 
             // Loop through each recursive child
-            foreach (var child in children)
+            foreach (var child in children.Items)
             {
                 var userdata = _userDataRepository.GetUserData(user, child);
 
@@ -1643,26 +1640,23 @@ namespace MediaBrowser.Server.Implementations.Dto
                     unplayed++;
                 }
 
-                if (addSyncInfo)
+                double percent = 0;
+                SyncedItemProgress syncItemProgress;
+                if (syncProgress.TryGetValue(child.Id.ToString("N"), out syncItemProgress))
                 {
-                    double percent = 0;
-                    SyncedItemProgress syncItemProgress;
-                    if (syncProgress.TryGetValue(child.Id.ToString("N"), out syncItemProgress))
+                    switch (syncItemProgress.Status)
                     {
-                        switch (syncItemProgress.Status)
-                        {
-                            case SyncJobItemStatus.Synced:
-                                percent = 100;
-                                break;
-                            case SyncJobItemStatus.Converting:
-                            case SyncJobItemStatus.ReadyToTransfer:
-                            case SyncJobItemStatus.Transferring:
-                                percent = 50;
-                                break;
-                        }
+                        case SyncJobItemStatus.Synced:
+                            percent = 100;
+                            break;
+                        case SyncJobItemStatus.Converting:
+                        case SyncJobItemStatus.ReadyToTransfer:
+                        case SyncJobItemStatus.Transferring:
+                            percent = 50;
+                            break;
                     }
-                    totalSyncPercent += percent;
                 }
+                totalSyncPercent += percent;
             }
 
             dto.RecursiveItemCount = recursiveItemCount;
@@ -1672,13 +1666,10 @@ namespace MediaBrowser.Server.Implementations.Dto
             {
                 dto.UserData.PlayedPercentage = totalPercentPlayed / recursiveItemCount;
 
-                if (addSyncInfo)
+                var pct = totalSyncPercent / recursiveItemCount;
+                if (pct > 0)
                 {
-                    var pct = totalSyncPercent / recursiveItemCount;
-                    if (pct > 0)
-                    {
-                        dto.SyncPercent = pct;
-                    }
+                    dto.SyncPercent = pct;
                 }
             }
         }

+ 17 - 11
MediaBrowser.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs

@@ -8,6 +8,7 @@ using MediaBrowser.Model.Tasks;
 using System;
 using System.Linq;
 using System.Threading;
+using System.Threading.Tasks;
 using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Model.LiveTv;
 
@@ -52,24 +53,29 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
             }
         }
 
-        private void TimerCallback(object state)
+        private async void TimerCallback(object state)
         {
-            if (_config.Configuration.EnableAutomaticRestart && IsIdle())
+            if (_config.Configuration.EnableAutomaticRestart)
             {
-                DisposeTimer();
+                var isIdle = await IsIdle().ConfigureAwait(false);
 
-                try
+                if (isIdle)
                 {
-                    _appHost.Restart();
-                }
-                catch (Exception ex)
-                {
-                    _logger.ErrorException("Error restarting server", ex);
+                    DisposeTimer();
+
+                    try
+                    {
+                        _appHost.Restart();
+                    }
+                    catch (Exception ex)
+                    {
+                        _logger.ErrorException("Error restarting server", ex);
+                    }
                 }
             }
         }
 
-        private bool IsIdle()
+        private async Task<bool> IsIdle()
         {
             if (_iTaskManager.ScheduledTasks.Any(i => i.State != TaskState.Idle))
             {
@@ -80,7 +86,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
             {
                 try
                 {
-                    var timers = _liveTvManager.GetTimers(new TimerQuery(), CancellationToken.None).Result;
+                    var timers = await _liveTvManager.GetTimers(new TimerQuery(), CancellationToken.None).ConfigureAwait(false);
                     if (timers.Items.Any(i => i.Status == RecordingStatus.InProgress))
                     {
                         return false;

+ 1 - 1
MediaBrowser.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs

@@ -119,7 +119,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
                         .DistinctBy(i => i.Id)
                         .Select(i =>
                         {
-                            var dto = _userDataManager.GetUserDataDto(i, user);
+                            var dto = _userDataManager.GetUserDataDto(i, user).Result;
                             dto.ItemId = i.Id.ToString("N");
                             return dto;
                         })

+ 5 - 5
MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs

@@ -294,7 +294,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
             return null;
         }
 
-        public object GetStaticFileResult(IRequest requestContext,
+        public Task<object> GetStaticFileResult(IRequest requestContext,
             string path,
             FileShare fileShare = FileShare.Read)
         {
@@ -310,7 +310,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
             });
         }
 
-        public object GetStaticFileResult(IRequest requestContext,
+        public Task<object> GetStaticFileResult(IRequest requestContext,
             StaticFileResultOptions options)
         {
             var path = options.Path;
@@ -351,7 +351,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
             return _fileSystem.GetFileStream(path, FileMode.Open, FileAccess.Read, fileShare);
         }
 
-        public object GetStaticResult(IRequest requestContext,
+        public Task<object> GetStaticResult(IRequest requestContext,
             Guid cacheKey,
             DateTime? lastDateModified,
             TimeSpan? cacheDuration,
@@ -372,7 +372,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
             });
         }
 
-        public object GetStaticResult(IRequest requestContext, StaticResultOptions options)
+        public async Task<object> GetStaticResult(IRequest requestContext, StaticResultOptions options)
         {
             var cacheKey = options.CacheKey;
             options.ResponseHeaders = options.ResponseHeaders ?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
@@ -398,7 +398,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
             }
 
             var compress = ShouldCompressResponse(requestContext, contentType);
-            var hasOptions = GetStaticResult(requestContext, options, compress).Result;
+            var hasOptions = await GetStaticResult(requestContext, options, compress).ConfigureAwait(false);
             AddResponseHeaders(hasOptions, options.ResponseHeaders);
 
             return hasOptions;

+ 1 - 1
MediaBrowser.Server.Implementations/HttpServer/SwaggerService.cs

@@ -25,7 +25,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
 
             var requestedFile = Path.Combine(swaggerDirectory, request.ResourceName.Replace('/', Path.DirectorySeparatorChar));
 
-            return ResultFactory.GetStaticFileResult(Request, requestedFile);
+            return ResultFactory.GetStaticFileResult(Request, requestedFile).Result;
         }
 
         /// <summary>

+ 1 - 1
MediaBrowser.Server.Implementations/Library/LibraryManager.cs

@@ -1398,7 +1398,7 @@ namespace MediaBrowser.Server.Implementations.Library
                     return true;
                 }
 
-                _logger.Debug("Query requires ancestor query due to type: " + i.GetType().Name);
+                //_logger.Debug("Query requires ancestor query due to type: " + i.GetType().Name);
                 return false;
 
             }))

+ 11 - 2
MediaBrowser.Server.Implementations/Library/UserDataManager.cs

@@ -202,12 +202,21 @@ namespace MediaBrowser.Server.Implementations.Library
             return GetUserData(userId, item.Id, item.GetUserDataKeys());
         }
 
-        public UserItemDataDto GetUserDataDto(IHasUserData item, User user)
+        public async Task<UserItemDataDto> GetUserDataDto(IHasUserData item, User user)
         {
             var userData = GetUserData(user.Id, item);
             var dto = GetUserItemDataDto(userData);
 
-            item.FillUserDataDtoValues(dto, userData, user);
+            await item.FillUserDataDtoValues(dto, userData, null, user).ConfigureAwait(false);
+            return dto;
+        }
+
+        public async Task<UserItemDataDto> GetUserDataDto(IHasUserData item, BaseItemDto itemDto, User user)
+        {
+            var userData = GetUserData(user.Id, item);
+            var dto = GetUserItemDataDto(userData);
+
+            await item.FillUserDataDtoValues(dto, userData, itemDto, user).ConfigureAwait(false);
             return dto;
         }
 

+ 1 - 1
MediaBrowser.Server.Implementations/Library/UserManager.cs

@@ -729,7 +729,7 @@ namespace MediaBrowser.Server.Implementations.Library
 
             var text = new StringBuilder();
 
-            var localAddress = _appHost.LocalApiUrl ?? string.Empty;
+            var localAddress = _appHost.GetLocalApiUrl().Result ?? string.Empty;
 
             text.AppendLine("Use your web browser to visit:");
             text.AppendLine(string.Empty);

+ 3 - 3
MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs

@@ -924,7 +924,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 
             var queryResult = _libraryManager.QueryItems(internalQuery);
 
-            var returnArray = _dtoService.GetBaseItemDtos(queryResult.Items, options, user).ToArray();
+            var returnArray = (await _dtoService.GetBaseItemDtos(queryResult.Items, options, user).ConfigureAwait(false)).ToArray();
 
             var result = new QueryResult<BaseItemDto>
             {
@@ -1001,7 +1001,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 
             var user = _userManager.GetUserById(query.UserId);
 
-            var returnArray = _dtoService.GetBaseItemDtos(internalResult.Items, options, user).ToArray();
+            var returnArray = (await _dtoService.GetBaseItemDtos(internalResult.Items, options, user).ConfigureAwait(false)).ToArray();
 
             var result = new QueryResult<BaseItemDto>
             {
@@ -1638,7 +1638,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 
             var internalResult = await GetInternalRecordings(query, cancellationToken).ConfigureAwait(false);
 
-            var returnArray = _dtoService.GetBaseItemDtos(internalResult.Items, options, user).ToArray();
+            var returnArray = (await _dtoService.GetBaseItemDtos(internalResult.Items, options, user).ConfigureAwait(false)).ToArray();
 
             return new QueryResult<BaseItemDto>
             {

+ 1 - 1
MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs

@@ -83,7 +83,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             }
 
             var list = sources.ToList();
-            var serverUrl = _appHost.LocalApiUrl;
+            var serverUrl = await _appHost.GetLocalApiUrl().ConfigureAwait(false);
 
             foreach (var source in list)
             {

+ 19 - 10
MediaBrowser.Server.Implementations/Session/SessionManager.cs

@@ -932,7 +932,7 @@ namespace MediaBrowser.Server.Implementations.Session
             return session.SessionController.SendGeneralCommand(command, cancellationToken);
         }
 
-        public Task SendPlayCommand(string controllingSessionId, string sessionId, PlayRequest command, CancellationToken cancellationToken)
+        public async Task SendPlayCommand(string controllingSessionId, string sessionId, PlayRequest command, CancellationToken cancellationToken)
         {
             var session = GetSessionToRemoteControl(sessionId);
 
@@ -950,7 +950,14 @@ namespace MediaBrowser.Server.Implementations.Session
             }
             else
             {
-                items = command.ItemIds.SelectMany(i => TranslateItemForPlayback(i, user))
+                var list = new List<BaseItem>();
+                foreach (var itemId in command.ItemIds)
+                {
+                    var subItems = await TranslateItemForPlayback(itemId, user).ConfigureAwait(false);
+                    list.AddRange(subItems);
+                }
+                
+                items = list
                    .Where(i => i.LocationType != LocationType.Virtual)
                    .ToList();
             }
@@ -1013,10 +1020,10 @@ namespace MediaBrowser.Server.Implementations.Session
                 command.ControllingUserId = controllingSession.UserId.Value.ToString("N");
             }
 
-            return session.SessionController.SendPlayCommand(command, cancellationToken);
+            await session.SessionController.SendPlayCommand(command, cancellationToken).ConfigureAwait(false);
         }
 
-        private IEnumerable<BaseItem> TranslateItemForPlayback(string id, User user)
+        private async Task<List<BaseItem>> TranslateItemForPlayback(string id, User user)
         {
             var item = _libraryManager.GetItemById(id);
 
@@ -1037,25 +1044,27 @@ namespace MediaBrowser.Server.Implementations.Session
                 });
 
                 return FilterToSingleMediaType(items)
-                    .OrderBy(i => i.SortName);
+                    .OrderBy(i => i.SortName)
+                    .ToList();
             }
 
             if (item.IsFolder)
             {
                 var folder = (Folder)item;
 
-                var items = folder.GetItems(new InternalItemsQuery(user)
+                var itemsResult = await folder.GetItems(new InternalItemsQuery(user)
                 {
                     Recursive = true,
                     IsFolder = false
 
-                }).Result.Items;
+                }).ConfigureAwait(false);
 
-                return FilterToSingleMediaType(items)
-                    .OrderBy(i => i.SortName);
+                return FilterToSingleMediaType(itemsResult.Items)
+                    .OrderBy(i => i.SortName)
+                    .ToList();
             }
 
-            return new[] { item };
+            return new List<BaseItem> { item };
         }
 
         private IEnumerable<BaseItem> FilterToSingleMediaType(IEnumerable<BaseItem> items)

+ 23 - 9
MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs

@@ -234,10 +234,22 @@ namespace MediaBrowser.Server.Implementations.Sync
 
         public async Task<IEnumerable<BaseItem>> GetItemsForSync(SyncCategory? category, string parentId, IEnumerable<string> itemIds, User user, bool unwatchedOnly)
         {
-            var items = category.HasValue ?
-                await GetItemsForSync(category.Value, parentId, user).ConfigureAwait(false) :
-                itemIds.SelectMany(i => GetItemsForSync(i, user));
+            var list = new List<BaseItem>();
 
+            if (category.HasValue)
+            {
+                list = (await GetItemsForSync(category.Value, parentId, user).ConfigureAwait(false)).ToList();
+            }
+            else
+            {
+                foreach (var itemId in itemIds)
+                {
+                    var subList = await GetItemsForSync(itemId, user).ConfigureAwait(false);
+                    list.AddRange(subList);
+                }
+            }
+
+            IEnumerable<BaseItem> items = list;
             items = items.Where(_syncManager.SupportsSync);
 
             if (unwatchedOnly)
@@ -314,7 +326,7 @@ namespace MediaBrowser.Server.Implementations.Sync
             return result.Items;
         }
 
-        private IEnumerable<BaseItem> GetItemsForSync(string id, User user)
+        private async Task<List<BaseItem>> GetItemsForSync(string id, User user)
         {
             var item = _libraryManager.GetItemById(id);
 
@@ -330,18 +342,20 @@ namespace MediaBrowser.Server.Implementations.Sync
                 {
                     IsFolder = false,
                     Recursive = true
-                });
+                }).ToList();
             }
 
             if (item.IsFolder)
             {
                 var folder = (Folder)item;
-                var items = folder.GetItems(new InternalItemsQuery(user)
+                var itemsResult = await folder.GetItems(new InternalItemsQuery(user)
                 {
                     Recursive = true,
                     IsFolder = false
 
-                }).Result.Items;
+                }).ConfigureAwait(false);
+
+                var items = itemsResult.Items;
 
                 if (!folder.IsPreSorted)
                 {
@@ -349,10 +363,10 @@ namespace MediaBrowser.Server.Implementations.Sync
                         .ToArray();
                 }
 
-                return items;
+                return items.ToList();
             }
 
-            return new[] { item };
+            return new List<BaseItem> { item };
         }
 
         private async Task EnsureSyncJobItems(string targetId, CancellationToken cancellationToken)

+ 6 - 6
MediaBrowser.Server.Implementations/Udp/UdpServer.cs

@@ -96,20 +96,20 @@ namespace MediaBrowser.Server.Implementations.Udp
 
         private async void RespondToV1Message(string endpoint, Encoding encoding)
         {
-            var localAddress = _appHost.LocalApiUrl;
+            var localUrl = await _appHost.GetLocalApiUrl().ConfigureAwait(false);
 
-            if (!string.IsNullOrEmpty(localAddress))
+            if (!string.IsNullOrEmpty(localUrl))
             {
                 // This is how we did the old v1 search, so need to strip off the protocol
-                var index = localAddress.IndexOf("://", StringComparison.OrdinalIgnoreCase);
+                var index = localUrl.IndexOf("://", StringComparison.OrdinalIgnoreCase);
 
                 if (index != -1)
                 {
-                    localAddress = localAddress.Substring(index + 3);
+                    localUrl = localUrl.Substring(index + 3);
                 }
 
                 // Send a response back with our ip address and port
-                var response = String.Format("MediaBrowserServer|{0}", localAddress);
+                var response = String.Format("MediaBrowserServer|{0}", localUrl);
 
                 await SendAsync(Encoding.UTF8.GetBytes(response), endpoint);
             }
@@ -121,7 +121,7 @@ namespace MediaBrowser.Server.Implementations.Udp
 
         private async void RespondToV2Message(string endpoint, Encoding encoding)
         {
-            var localUrl = _appHost.LocalApiUrl;
+            var localUrl = await _appHost.GetLocalApiUrl().ConfigureAwait(false);
 
             if (!string.IsNullOrEmpty(localUrl))
             {

+ 19 - 30
MediaBrowser.Server.Startup.Common/ApplicationHost.cs

@@ -313,7 +313,6 @@ namespace MediaBrowser.Server.Startup.Common
         /// <summary>
         /// Runs the startup tasks.
         /// </summary>
-        /// <returns>Task.</returns>
         public override async Task RunStartupTasks()
         {
             if (ServerConfigurationManager.Configuration.MigrationVersion < CleanDatabaseScheduledTask.MigrationVersion &&
@@ -402,7 +401,6 @@ namespace MediaBrowser.Server.Startup.Common
         /// <summary>
         /// Registers resources that classes will depend on
         /// </summary>
-        /// <returns>Task.</returns>
         protected override async Task RegisterResources(IProgress<double> progress)
         {
             await base.RegisterResources(progress).ConfigureAwait(false);
@@ -727,7 +725,6 @@ namespace MediaBrowser.Server.Startup.Common
         /// <summary>
         /// Configures the repositories.
         /// </summary>
-        /// <returns>Task.</returns>
         private async Task ConfigureNotificationsRepository()
         {
             var repo = new SqliteNotificationsRepository(LogManager, ApplicationPaths, NativeApp.GetDbConnector());
@@ -742,7 +739,6 @@ namespace MediaBrowser.Server.Startup.Common
         /// <summary>
         /// Configures the user data repositories.
         /// </summary>
-        /// <returns>Task.</returns>
         private async Task ConfigureUserDataRepositories()
         {
             var repo = new SqliteUserDataRepository(LogManager, ApplicationPaths, NativeApp.GetDbConnector());
@@ -1102,7 +1098,7 @@ namespace MediaBrowser.Server.Startup.Common
         /// Gets the system status.
         /// </summary>
         /// <returns>SystemInfo.</returns>
-        public virtual SystemInfo GetSystemInfo()
+        public SystemInfo GetSystemInfo()
         {
             return new SystemInfo
             {
@@ -1134,7 +1130,7 @@ namespace MediaBrowser.Server.Startup.Common
                 IsRunningAsService = IsRunningAsService,
                 SupportsRunningAsService = SupportsRunningAsService,
                 ServerName = FriendlyName,
-                LocalAddress = LocalApiUrl,
+                LocalAddress = GetLocalApiUrl().Result,
                 SupportsLibraryMonitor = SupportsLibraryMonitor
             };
         }
@@ -1152,29 +1148,26 @@ namespace MediaBrowser.Server.Startup.Common
             get { return !string.IsNullOrWhiteSpace(HttpServer.CertificatePath); }
         }
 
-        public string LocalApiUrl
+        public async Task<string> GetLocalApiUrl()
         {
-            get
+            try
             {
-                try
-                {
-                    // Return the first matched address, if found, or the first known local address
-                    var address = LocalIpAddresses.FirstOrDefault(i => !IPAddress.IsLoopback(i));
-
-                    if (address != null)
-                    {
-                        return GetLocalApiUrl(address);
-                    }
+                // Return the first matched address, if found, or the first known local address
+                var address = (await GetLocalIpAddresses().ConfigureAwait(false)).FirstOrDefault(i => !IPAddress.IsLoopback(i));
 
-                    return null;
-                }
-                catch (Exception ex)
+                if (address != null)
                 {
-                    Logger.ErrorException("Error getting local Ip address information", ex);
+                    return GetLocalApiUrl(address);
                 }
 
                 return null;
             }
+            catch (Exception ex)
+            {
+                Logger.ErrorException("Error getting local Ip address information", ex);
+            }
+
+            return null;
         }
 
         public string GetLocalApiUrl(IPAddress ipAddress)
@@ -1194,16 +1187,13 @@ namespace MediaBrowser.Server.Startup.Common
                 HttpPort.ToString(CultureInfo.InvariantCulture));
         }
 
-        public List<IPAddress> LocalIpAddresses
+        public async Task<List<IPAddress>> GetLocalIpAddresses()
         {
-            get
-            {
-                var localAddresses = NetworkManager.GetLocalIpAddresses()
-                    .Where(IsIpAddressValid)
-                    .ToList();
+            var localAddresses = NetworkManager.GetLocalIpAddresses()
+                .Where(IsIpAddressValid)
+                .ToList();
 
-                return localAddresses;
-            }
+            return localAddresses;
         }
 
         private readonly ConcurrentDictionary<string, bool> _validAddressResults = new ConcurrentDictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
@@ -1389,7 +1379,6 @@ namespace MediaBrowser.Server.Startup.Common
         /// <param name="package">The package that contains the update</param>
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <param name="progress">The progress.</param>
-        /// <returns>Task.</returns>
         public override async Task UpdateApplication(PackageVersionInfo package, CancellationToken cancellationToken, IProgress<double> progress)
         {
             await InstallationManager.InstallPackage(package, false, progress, cancellationToken).ConfigureAwait(false);

+ 5 - 4
MediaBrowser.WebDashboard/Api/DashboardService.cs

@@ -133,7 +133,7 @@ namespace MediaBrowser.WebDashboard.Api
         /// </summary>
         /// <param name="request">The request.</param>
         /// <returns>System.Object.</returns>
-        public object Get(GetDashboardConfigurationPage request)
+        public Task<object> Get(GetDashboardConfigurationPage request)
         {
             var page = ServerEntryPoint.Instance.PluginConfigurationPages.First(p => p.Name.Equals(request.Name, StringComparison.OrdinalIgnoreCase));
 
@@ -201,7 +201,7 @@ namespace MediaBrowser.WebDashboard.Api
         /// </summary>
         /// <param name="request">The request.</param>
         /// <returns>System.Object.</returns>
-        public object Get(GetDashboardResource request)
+        public async Task<object> Get(GetDashboardResource request)
         {
             var path = request.ResourceName;
 
@@ -230,7 +230,8 @@ namespace MediaBrowser.WebDashboard.Api
                 !contentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase) &&
                 !contentType.StartsWith("font/", StringComparison.OrdinalIgnoreCase))
             {
-                return ResultFactory.GetResult(GetResourceStream(path, localizationCulture).Result, contentType);
+                var stream = await GetResourceStream(path, localizationCulture).ConfigureAwait(false);
+                return ResultFactory.GetResult(stream, contentType);
             }
 
             TimeSpan? cacheDuration = null;
@@ -246,7 +247,7 @@ namespace MediaBrowser.WebDashboard.Api
 
             var cacheKey = (assembly.Version + (localizationCulture ?? string.Empty) + path).GetMD5();
 
-            return ResultFactory.GetStaticResult(Request, cacheKey, null, cacheDuration, contentType, () => GetResourceStream(path, localizationCulture));
+            return await ResultFactory.GetStaticResult(Request, cacheKey, null, cacheDuration, contentType, () => GetResourceStream(path, localizationCulture)).ConfigureAwait(false);
         }
 
         private string GetLocalizationCulture()