浏览代码

Fix some 'bugs' flagged by sonarcloud

Bond_009 5 年之前
父节点
当前提交
10e381f66f

+ 1 - 1
DvdLib/Ifo/Program.cs

@@ -6,7 +6,7 @@ namespace DvdLib.Ifo
 {
     public class Program
     {
-        public readonly List<Cell> Cells;
+        public IReadOnlyList<Cell> Cells { get; }
 
         public Program(List<Cell> cells)
         {

+ 2 - 6
Emby.Dlna/ContentDirectory/ContentDirectory.cs

@@ -1,6 +1,7 @@
 #pragma warning disable CS1591
 
 using System;
+using System.Linq;
 using System.Threading.Tasks;
 using Emby.Dlna.Service;
 using MediaBrowser.Common.Net;
@@ -136,12 +137,7 @@ namespace Emby.Dlna.ContentDirectory
                 }
             }
 
-            foreach (var user in _userManager.Users)
-            {
-                return user;
-            }
-
-            return null;
+            return _userManager.Users.FirstOrDefault();
         }
     }
 }

+ 5 - 5
Emby.Dlna/Main/DlnaEntryPoint.cs

@@ -133,20 +133,20 @@ namespace Emby.Dlna.Main
         {
             await ((DlnaManager)_dlnaManager).InitProfilesAsync().ConfigureAwait(false);
 
-            ReloadComponents();
+            await ReloadComponents().ConfigureAwait(false);
 
-            _config.NamedConfigurationUpdated += _config_NamedConfigurationUpdated;
+            _config.NamedConfigurationUpdated += OnNamedConfigurationUpdated;
         }
 
-        void _config_NamedConfigurationUpdated(object sender, ConfigurationUpdateEventArgs e)
+        private async void OnNamedConfigurationUpdated(object sender, ConfigurationUpdateEventArgs e)
         {
             if (string.Equals(e.Key, "dlna", StringComparison.OrdinalIgnoreCase))
             {
-                ReloadComponents();
+                await ReloadComponents().ConfigureAwait(false);
             }
         }
 
-        private async void ReloadComponents()
+        private async Task ReloadComponents()
         {
             var options = _config.GetDlnaConfiguration();
 

+ 10 - 10
Emby.Dlna/PlayTo/Device.cs

@@ -34,7 +34,7 @@ namespace Emby.Dlna.PlayTo
         {
             get
             {
-                RefreshVolumeIfNeeded();
+                RefreshVolumeIfNeeded().GetAwaiter().GetResult();
                 return _volume;
             }
             set => _volume = value;
@@ -76,24 +76,24 @@ namespace Emby.Dlna.PlayTo
 
         private DateTime _lastVolumeRefresh;
         private bool _volumeRefreshActive;
-        private void RefreshVolumeIfNeeded()
+        private Task RefreshVolumeIfNeeded()
         {
-            if (!_volumeRefreshActive)
-            {
-                return;
-            }
-
-            if (DateTime.UtcNow >= _lastVolumeRefresh.AddSeconds(5))
+            if (_volumeRefreshActive
+                && DateTime.UtcNow >= _lastVolumeRefresh.AddSeconds(5))
             {
                 _lastVolumeRefresh = DateTime.UtcNow;
-                RefreshVolume(CancellationToken.None);
+                return RefreshVolume();
             }
+
+            return Task.CompletedTask;
         }
 
-        private async void RefreshVolume(CancellationToken cancellationToken)
+        private async Task RefreshVolume(CancellationToken cancellationToken = default)
         {
             if (_disposed)
+            {
                 return;
+            }
 
             try
             {

+ 12 - 7
Emby.Dlna/PlayTo/PlayToController.cs

@@ -146,11 +146,14 @@ namespace Emby.Dlna.PlayTo
                 {
                     var positionTicks = GetProgressPositionTicks(streamInfo);
 
-                    ReportPlaybackStopped(streamInfo, positionTicks);
+                    await ReportPlaybackStopped(streamInfo, positionTicks).ConfigureAwait(false);
                 }
 
                 streamInfo = StreamParams.ParseFromUrl(e.NewMediaInfo.Url, _libraryManager, _mediaSourceManager);
-                if (streamInfo.Item == null) return;
+                if (streamInfo.Item == null)
+                {
+                    return;
+                }
 
                 var newItemProgress = GetProgressInfo(streamInfo);
 
@@ -173,11 +176,14 @@ namespace Emby.Dlna.PlayTo
             {
                 var streamInfo = StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager, _mediaSourceManager);
 
-                if (streamInfo.Item == null) return;
+                if (streamInfo.Item == null)
+                {
+                    return;
+                }
 
                 var positionTicks = GetProgressPositionTicks(streamInfo);
 
-                ReportPlaybackStopped(streamInfo, positionTicks);
+                await ReportPlaybackStopped(streamInfo, positionTicks).ConfigureAwait(false);
 
                 var mediaSource = await streamInfo.GetMediaSource(CancellationToken.None).ConfigureAwait(false);
 
@@ -185,7 +191,7 @@ namespace Emby.Dlna.PlayTo
                     (_device.Duration == null ? (long?)null : _device.Duration.Value.Ticks) :
                     mediaSource.RunTimeTicks;
 
-                var playedToCompletion = (positionTicks.HasValue && positionTicks.Value == 0);
+                var playedToCompletion = positionTicks.HasValue && positionTicks.Value == 0;
 
                 if (!playedToCompletion && duration.HasValue && positionTicks.HasValue)
                 {
@@ -210,7 +216,7 @@ namespace Emby.Dlna.PlayTo
             }
         }
 
-        private async void ReportPlaybackStopped(StreamParams streamInfo, long? positionTicks)
+        private async Task ReportPlaybackStopped(StreamParams streamInfo, long? positionTicks)
         {
             try
             {
@@ -220,7 +226,6 @@ namespace Emby.Dlna.PlayTo
                     SessionId = _session.Id,
                     PositionTicks = positionTicks,
                     MediaSourceId = streamInfo.MediaSourceId
-
                 }).ConfigureAwait(false);
             }
             catch (Exception ex)

+ 4 - 10
Emby.Dlna/Ssdp/Extensions.cs

@@ -1,5 +1,6 @@
 #pragma warning disable CS1591
 
+using System.Linq;
 using System.Xml.Linq;
 
 namespace Emby.Dlna.Ssdp
@@ -10,24 +11,17 @@ namespace Emby.Dlna.Ssdp
         {
             var node = container.Element(name);
 
-            return node == null ? null : node.Value;
+            return node?.Value;
         }
 
         public static string GetAttributeValue(this XElement container, XName name)
         {
             var node = container.Attribute(name);
 
-            return node == null ? null : node.Value;
+            return node?.Value;
         }
 
         public static string GetDescendantValue(this XElement container, XName name)
-        {
-            foreach (var node in container.Descendants(name))
-            {
-                return node.Value;
-            }
-
-            return null;
-        }
+            => container.Descendants(name).FirstOrDefault()?.Value;
     }
 }

+ 2 - 2
Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs

@@ -302,7 +302,7 @@ namespace Emby.Server.Implementations.EntryPoints
                                     .Select(x => x.First())
                                     .ToList();
 
-                SendChangeNotifications(_itemsAdded.ToList(), itemsUpdated, _itemsRemoved.ToList(), foldersAddedTo, foldersRemovedFrom, CancellationToken.None);
+                SendChangeNotifications(_itemsAdded.ToList(), itemsUpdated, _itemsRemoved.ToList(), foldersAddedTo, foldersRemovedFrom, CancellationToken.None).GetAwaiter().GetResult();
 
                 if (LibraryUpdateTimer != null)
                 {
@@ -327,7 +327,7 @@ namespace Emby.Server.Implementations.EntryPoints
         /// <param name="foldersAddedTo">The folders added to.</param>
         /// <param name="foldersRemovedFrom">The folders removed from.</param>
         /// <param name="cancellationToken">The cancellation token.</param>
-        private async void SendChangeNotifications(List<BaseItem> itemsAdded, List<BaseItem> itemsUpdated, List<BaseItem> itemsRemoved, List<Folder> foldersAddedTo, List<Folder> foldersRemovedFrom, CancellationToken cancellationToken)
+        private async Task SendChangeNotifications(List<BaseItem> itemsAdded, List<BaseItem> itemsUpdated, List<BaseItem> itemsRemoved, List<Folder> foldersAddedTo, List<Folder> foldersRemovedFrom, CancellationToken cancellationToken)
         {
             var userIds = _sessionManager.Sessions
                 .Select(i => i.UserId)

+ 9 - 9
Emby.Server.Implementations/EntryPoints/RecordingNotifier.cs

@@ -42,27 +42,27 @@ namespace Emby.Server.Implementations.EntryPoints
             return Task.CompletedTask;
         }
 
-        private void OnLiveTvManagerSeriesTimerCreated(object sender, MediaBrowser.Model.Events.GenericEventArgs<TimerEventInfo> e)
+        private async void OnLiveTvManagerSeriesTimerCreated(object sender, MediaBrowser.Model.Events.GenericEventArgs<TimerEventInfo> e)
         {
-            SendMessage("SeriesTimerCreated", e.Argument);
+            await SendMessage("SeriesTimerCreated", e.Argument).ConfigureAwait(false);
         }
 
-        private void OnLiveTvManagerTimerCreated(object sender, MediaBrowser.Model.Events.GenericEventArgs<TimerEventInfo> e)
+        private async void OnLiveTvManagerTimerCreated(object sender, MediaBrowser.Model.Events.GenericEventArgs<TimerEventInfo> e)
         {
-            SendMessage("TimerCreated", e.Argument);
+            await SendMessage("TimerCreated", e.Argument).ConfigureAwait(false);
         }
 
-        private void OnLiveTvManagerSeriesTimerCancelled(object sender, MediaBrowser.Model.Events.GenericEventArgs<TimerEventInfo> e)
+        private async void OnLiveTvManagerSeriesTimerCancelled(object sender, MediaBrowser.Model.Events.GenericEventArgs<TimerEventInfo> e)
         {
-            SendMessage("SeriesTimerCancelled", e.Argument);
+            await SendMessage("SeriesTimerCancelled", e.Argument).ConfigureAwait(false);
         }
 
-        private void OnLiveTvManagerTimerCancelled(object sender, MediaBrowser.Model.Events.GenericEventArgs<TimerEventInfo> e)
+        private async void OnLiveTvManagerTimerCancelled(object sender, MediaBrowser.Model.Events.GenericEventArgs<TimerEventInfo> e)
         {
-            SendMessage("TimerCancelled", e.Argument);
+            await SendMessage("TimerCancelled", e.Argument).ConfigureAwait(false);
         }
 
-        private async void SendMessage(string name, TimerEventInfo info)
+        private async Task SendMessage(string name, TimerEventInfo info)
         {
             var users = _userManager.Users.Where(i => i.Policy.EnableLiveTvAccess).Select(i => i.Id).ToList();
 

+ 24 - 24
Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs

@@ -85,29 +85,29 @@ namespace Emby.Server.Implementations.EntryPoints
             return Task.CompletedTask;
         }
 
-        private void OnPackageInstalling(object sender, InstallationEventArgs e)
+        private async void OnPackageInstalling(object sender, InstallationEventArgs e)
         {
-            SendMessageToAdminSessions("PackageInstalling", e.InstallationInfo);
+            await SendMessageToAdminSessions("PackageInstalling", e.InstallationInfo).ConfigureAwait(false);
         }
 
-        private void OnPackageInstallationCancelled(object sender, InstallationEventArgs e)
+        private async void OnPackageInstallationCancelled(object sender, InstallationEventArgs e)
         {
-            SendMessageToAdminSessions("PackageInstallationCancelled", e.InstallationInfo);
+            await SendMessageToAdminSessions("PackageInstallationCancelled", e.InstallationInfo).ConfigureAwait(false);
         }
 
-        private void OnPackageInstallationCompleted(object sender, InstallationEventArgs e)
+        private async void OnPackageInstallationCompleted(object sender, InstallationEventArgs e)
         {
-            SendMessageToAdminSessions("PackageInstallationCompleted", e.InstallationInfo);
+            await SendMessageToAdminSessions("PackageInstallationCompleted", e.InstallationInfo).ConfigureAwait(false);
         }
 
-        private void OnPackageInstallationFailed(object sender, InstallationFailedEventArgs e)
+        private async void OnPackageInstallationFailed(object sender, InstallationFailedEventArgs e)
         {
-            SendMessageToAdminSessions("PackageInstallationFailed", e.InstallationInfo);
+            await SendMessageToAdminSessions("PackageInstallationFailed", e.InstallationInfo).ConfigureAwait(false);
         }
 
-        private void OnTaskCompleted(object sender, TaskCompletionEventArgs e)
+        private async void OnTaskCompleted(object sender, TaskCompletionEventArgs e)
         {
-            SendMessageToAdminSessions("ScheduledTaskEnded", e.Result);
+            await SendMessageToAdminSessions("ScheduledTaskEnded", e.Result).ConfigureAwait(false);
         }
 
         /// <summary>
@@ -115,9 +115,9 @@ namespace Emby.Server.Implementations.EntryPoints
         /// </summary>
         /// <param name="sender">The sender.</param>
         /// <param name="e">The e.</param>
-        private void OnPluginUninstalled(object sender, GenericEventArgs<IPlugin> e)
+        private async void OnPluginUninstalled(object sender, GenericEventArgs<IPlugin> e)
         {
-            SendMessageToAdminSessions("PluginUninstalled", e.Argument.GetPluginInfo());
+            await SendMessageToAdminSessions("PluginUninstalled", e.Argument.GetPluginInfo()).ConfigureAwait(false);
         }
 
         /// <summary>
@@ -125,9 +125,9 @@ namespace Emby.Server.Implementations.EntryPoints
         /// </summary>
         /// <param name="sender">The source of the event.</param>
         /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
-        private void OnHasPendingRestartChanged(object sender, EventArgs e)
+        private async void OnHasPendingRestartChanged(object sender, EventArgs e)
         {
-            _sessionManager.SendRestartRequiredNotification(CancellationToken.None);
+            await _sessionManager.SendRestartRequiredNotification(CancellationToken.None).ConfigureAwait(false);
         }
 
         /// <summary>
@@ -135,11 +135,11 @@ namespace Emby.Server.Implementations.EntryPoints
         /// </summary>
         /// <param name="sender">The sender.</param>
         /// <param name="e">The e.</param>
-        private void OnUserUpdated(object sender, GenericEventArgs<User> e)
+        private async void OnUserUpdated(object sender, GenericEventArgs<User> e)
         {
             var dto = _userManager.GetUserDto(e.Argument);
 
-            SendMessageToUserSession(e.Argument, "UserUpdated", dto);
+            await SendMessageToUserSession(e.Argument, "UserUpdated", dto).ConfigureAwait(false);
         }
 
         /// <summary>
@@ -147,26 +147,26 @@ namespace Emby.Server.Implementations.EntryPoints
         /// </summary>
         /// <param name="sender">The sender.</param>
         /// <param name="e">The e.</param>
-        private void OnUserDeleted(object sender, GenericEventArgs<User> e)
+        private async void OnUserDeleted(object sender, GenericEventArgs<User> e)
         {
-            SendMessageToUserSession(e.Argument, "UserDeleted", e.Argument.Id.ToString("N", CultureInfo.InvariantCulture));
+            await SendMessageToUserSession(e.Argument, "UserDeleted", e.Argument.Id.ToString("N", CultureInfo.InvariantCulture)).ConfigureAwait(false);
         }
 
-        private void OnUserPolicyUpdated(object sender, GenericEventArgs<User> e)
+        private async void OnUserPolicyUpdated(object sender, GenericEventArgs<User> e)
         {
             var dto = _userManager.GetUserDto(e.Argument);
 
-            SendMessageToUserSession(e.Argument, "UserPolicyUpdated", dto);
+            await SendMessageToUserSession(e.Argument, "UserPolicyUpdated", dto).ConfigureAwait(false);
         }
 
-        private void OnUserConfigurationUpdated(object sender, GenericEventArgs<User> e)
+        private async void OnUserConfigurationUpdated(object sender, GenericEventArgs<User> e)
         {
             var dto = _userManager.GetUserDto(e.Argument);
 
-            SendMessageToUserSession(e.Argument, "UserConfigurationUpdated", dto);
+            await SendMessageToUserSession(e.Argument, "UserConfigurationUpdated", dto).ConfigureAwait(false);
         }
 
-        private async void SendMessageToAdminSessions<T>(string name, T data)
+        private async Task SendMessageToAdminSessions<T>(string name, T data)
         {
             try
             {
@@ -178,7 +178,7 @@ namespace Emby.Server.Implementations.EntryPoints
             }
         }
 
-        private async void SendMessageToUserSession<T>(User user, string name, T data)
+        private async Task SendMessageToUserSession<T>(User user, string name, T data)
         {
             try
             {

+ 8 - 4
Emby.Server.Implementations/HttpServer/HttpResultFactory.cs

@@ -255,16 +255,20 @@ namespace Emby.Server.Implementations.HttpServer
         {
             var acceptEncoding = request.Headers[HeaderNames.AcceptEncoding].ToString();
 
-            if (string.IsNullOrEmpty(acceptEncoding))
+            if (!string.IsNullOrEmpty(acceptEncoding))
             {
-                //if (_brotliCompressor != null && acceptEncoding.IndexOf("br", StringComparison.OrdinalIgnoreCase) != -1)
+                // if (_brotliCompressor != null && acceptEncoding.IndexOf("br", StringComparison.OrdinalIgnoreCase) != -1)
                 //    return "br";
 
-                if (acceptEncoding.IndexOf("deflate", StringComparison.OrdinalIgnoreCase) != -1)
+                if (acceptEncoding.Contains("deflate", StringComparison.OrdinalIgnoreCase))
+                {
                     return "deflate";
+                }
 
-                if (acceptEncoding.IndexOf("gzip", StringComparison.OrdinalIgnoreCase) != -1)
+                if (acceptEncoding.Contains("gzip", StringComparison.OrdinalIgnoreCase))
+                {
                     return "gzip";
+                }
             }
 
             return null;

+ 4 - 9
Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs

@@ -140,11 +140,11 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
             }
         }
 
-        private void OnNamedConfigurationUpdated(object sender, ConfigurationUpdateEventArgs e)
+        private async void OnNamedConfigurationUpdated(object sender, ConfigurationUpdateEventArgs e)
         {
             if (string.Equals(e.Key, "livetv", StringComparison.OrdinalIgnoreCase))
             {
-                OnRecordingFoldersChanged();
+                await CreateRecordingFolders().ConfigureAwait(false);
             }
         }
 
@@ -155,11 +155,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
             return CreateRecordingFolders();
         }
 
-        private async void OnRecordingFoldersChanged()
-        {
-            await CreateRecordingFolders().ConfigureAwait(false);
-        }
-
         internal async Task CreateRecordingFolders()
         {
             try
@@ -1334,7 +1329,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
                     await CreateRecordingFolders().ConfigureAwait(false);
 
                     TriggerRefresh(recordPath);
-                    EnforceKeepUpTo(timer, seriesPath);
+                    await EnforceKeepUpTo(timer, seriesPath).ConfigureAwait(false);
                 };
 
                 await recorder.Record(directStreamProvider, mediaStreamInfo, recordPath, duration, onStarted, activeRecordingInfo.CancellationTokenSource.Token).ConfigureAwait(false);
@@ -1494,7 +1489,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
             return item;
         }
 
-        private async void EnforceKeepUpTo(TimerInfo timer, string seriesPath)
+        private async Task EnforceKeepUpTo(TimerInfo timer, string seriesPath)
         {
             if (string.IsNullOrWhiteSpace(timer.SeriesTimerId))
             {

+ 2 - 2
Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs

@@ -117,7 +117,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
             onStarted();
 
             // Important - don't await the log task or we won't be able to kill ffmpeg when the user stops playback
-            StartStreamingLog(_process.StandardError.BaseStream, _logFileStream);
+            _ = StartStreamingLog(_process.StandardError.BaseStream, _logFileStream);
 
             _logger.LogInformation("ffmpeg recording process started for {0}", _targetPath);
 
@@ -321,7 +321,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
             }
         }
 
-        private async void StartStreamingLog(Stream source, Stream target)
+        private async Task StartStreamingLog(Stream source, Stream target)
         {
             try
             {

+ 5 - 15
Emby.Server.Implementations/LiveTv/LiveTvManager.cs

@@ -788,22 +788,12 @@ namespace Emby.Server.Implementations.LiveTv
 
             if (query.OrderBy.Count == 0)
             {
-                if (query.IsAiring ?? false)
-                {
-                    // Unless something else was specified, order by start date to take advantage of a specialized index
-                    query.OrderBy = new[]
-                    {
-                        (ItemSortBy.StartDate, SortOrder.Ascending)
-                    };
-                }
-                else
+
+                // Unless something else was specified, order by start date to take advantage of a specialized index
+                query.OrderBy = new[]
                 {
-                    // Unless something else was specified, order by start date to take advantage of a specialized index
-                    query.OrderBy = new[]
-                    {
-                        (ItemSortBy.StartDate, SortOrder.Ascending)
-                    };
-                }
+                    (ItemSortBy.StartDate, SortOrder.Ascending)
+                };
             }
 
             RemoveFields(options);

+ 3 - 2
Emby.Server.Implementations/SocketSharp/WebSocketSharpRequest.cs

@@ -208,8 +208,9 @@ namespace Emby.Server.Implementations.SocketSharp
 
         private static string GetQueryStringContentType(HttpRequest httpReq)
         {
-            ReadOnlySpan<char> format = httpReq.Query["format"].ToString();
-            if (format == null)
+            string formatStr = httpReq.Query["format"].ToString();
+            ReadOnlySpan<char> format = formatStr;
+            if (formatStr == null)
             {
                 const int FormatMaxLength = 4;
                 ReadOnlySpan<char> pi = httpReq.Path.ToString();

+ 1 - 2
MediaBrowser.Api/Images/ImageService.cs

@@ -555,8 +555,7 @@ namespace MediaBrowser.Api.Images
             var imageInfo = GetImageInfo(request, item);
             if (imageInfo == null)
             {
-                var displayText = item == null ? itemId.ToString() : item.Name;
-                throw new ResourceNotFoundException(string.Format("{0} does not have an image of type {1}", displayText, request.Type));
+                throw new ResourceNotFoundException(string.Format("{0} does not have an image of type {1}", item.Name, request.Type));
             }
 
             bool cropwhitespace;

+ 14 - 14
MediaBrowser.Api/Sessions/SessionInfoWebSocketListener.cs

@@ -40,39 +40,39 @@ namespace MediaBrowser.Api.Sessions
             _sessionManager.SessionActivity += OnSessionManagerSessionActivity;
         }
 
-        private void OnSessionManagerSessionActivity(object sender, SessionEventArgs e)
+        private async void OnSessionManagerSessionActivity(object sender, SessionEventArgs e)
         {
-            SendData(false);
+            await SendData(false).ConfigureAwait(false);
         }
 
-        private void OnSessionManagerCapabilitiesChanged(object sender, SessionEventArgs e)
+        private async void OnSessionManagerCapabilitiesChanged(object sender, SessionEventArgs e)
         {
-            SendData(true);
+            await SendData(true).ConfigureAwait(false);
         }
 
-        private void OnSessionManagerPlaybackProgress(object sender, PlaybackProgressEventArgs e)
+        private async void OnSessionManagerPlaybackProgress(object sender, PlaybackProgressEventArgs e)
         {
-            SendData(!e.IsAutomated);
+            await SendData(!e.IsAutomated).ConfigureAwait(false);
         }
 
-        private void OnSessionManagerPlaybackStopped(object sender, PlaybackStopEventArgs e)
+        private async void OnSessionManagerPlaybackStopped(object sender, PlaybackStopEventArgs e)
         {
-            SendData(true);
+            await SendData(true).ConfigureAwait(false);
         }
 
-        private void OnSessionManagerPlaybackStart(object sender, PlaybackProgressEventArgs e)
+        private async void OnSessionManagerPlaybackStart(object sender, PlaybackProgressEventArgs e)
         {
-            SendData(true);
+            await SendData(true).ConfigureAwait(false);
         }
 
-        private void OnSessionManagerSessionEnded(object sender, SessionEventArgs e)
+        private async void OnSessionManagerSessionEnded(object sender, SessionEventArgs e)
         {
-            SendData(true);
+            await SendData(true).ConfigureAwait(false);
         }
 
-        private void OnSessionManagerSessionStarted(object sender, SessionEventArgs e)
+        private async void OnSessionManagerSessionStarted(object sender, SessionEventArgs e)
         {
-            SendData(true);
+            await SendData(true).ConfigureAwait(false);
         }
 
         /// <summary>

+ 16 - 9
MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs

@@ -104,7 +104,7 @@ namespace MediaBrowser.Controller.Net
             }
         }
 
-        protected void SendData(bool force)
+        protected async Task SendData(bool force)
         {
             Tuple<IWebSocketConnection, CancellationTokenSource, TStateType>[] tuples;
 
@@ -128,13 +128,18 @@ namespace MediaBrowser.Controller.Net
                     .ToArray();
             }
 
-            foreach (var tuple in tuples)
+            IEnumerable<Task> GetTasks()
             {
-                SendData(tuple);
+                foreach (var tuple in tuples)
+                {
+                    yield return SendData(tuple);
+                }
             }
+
+            await Task.WhenAll(GetTasks()).ConfigureAwait(false);
         }
 
-        private async void SendData(Tuple<IWebSocketConnection, CancellationTokenSource, TStateType> tuple)
+        private async Task SendData(Tuple<IWebSocketConnection, CancellationTokenSource, TStateType> tuple)
         {
             var connection = tuple.Item1;
 
@@ -148,11 +153,13 @@ namespace MediaBrowser.Controller.Net
 
                 if (data != null)
                 {
-                    await connection.SendAsync(new WebSocketMessage<TReturnDataType>
-                    {
-                        MessageType = Name,
-                        Data = data
-                    }, cancellationToken).ConfigureAwait(false);
+                    await connection.SendAsync(
+                        new WebSocketMessage<TReturnDataType>
+                        {
+                            MessageType = Name,
+                            Data = data
+                        },
+                        cancellationToken).ConfigureAwait(false);
 
                     state.DateLastSendUtc = DateTime.UtcNow;
                 }

+ 4 - 2
MediaBrowser.MediaEncoding/Subtitles/AssParser.cs

@@ -33,10 +33,12 @@ namespace MediaBrowser.MediaEncoding.Subtitles
                     {
                         continue;
                     }
+
                     if (line.StartsWith("["))
+                    {
                         break;
-                    if (string.IsNullOrEmpty(line))
-                        continue;
+                    }
+
                     var subEvent = new SubtitleTrackEvent { Id = eventIndex.ToString(_usCulture) };
                     eventIndex++;
                     var sections = line.Substring(10).Split(',');