private async Task <bool> TryPlayAsync(KeyValuePair <string, PlayableTrack> trackPair, bool silent = false)
        {
            if (trackPair.Value == null)
            {
                return(false);
            }
            if (this.isLoadingTrack)
            {
                return(true);                     // Only load 1 track at a time (just in case)
            }
            this.OnLoadingTrack(true);

            bool isPlaybackSuccess = true;
            PlaybackFailedEventArgs playbackFailedEventArgs = null;

            try
            {
                // If a Track was playing, make sure it is now stopped.
                this.StopPlayback();

                // Check that the file exists
                if (!System.IO.File.Exists(trackPair.Value.Path))
                {
                    throw new FileNotFoundException(string.Format("File '{0}' was not found", trackPair.Value.Path));
                }

                // Start playing
                await this.StartPlaybackAsync(trackPair, silent);

                // Playing was successful
                this.PlaybackSuccess(this.isPlayingPreviousTrack);

                // Set this to false again after raising the event. It is important to have a correct slide
                // direction for cover art when the next Track is a file from double click in Windows.
                this.isPlayingPreviousTrack = false;
                LogClient.Info("Playing the file {0}. EventMode={1}, ExclusiveMode={2}, LoopMode={3}, Shuffle={4}", trackPair.Value.Path, this.eventMode.ToString(), this.exclusiveMode.ToString(), this.LoopMode.ToString(), this.shuffle.ToString());
            }
            catch (FileNotFoundException fnfex)
            {
                playbackFailedEventArgs = new PlaybackFailedEventArgs {
                    FailureReason = PlaybackFailureReason.FileNotFound, Message = fnfex.Message, StackTrace = fnfex.StackTrace
                };
                isPlaybackSuccess = false;
            }
            catch (Exception ex)
            {
                playbackFailedEventArgs = new PlaybackFailedEventArgs {
                    FailureReason = PlaybackFailureReason.Unknown, Message = ex.Message, StackTrace = ex.StackTrace
                };
                isPlaybackSuccess = false;
            }

            if (!isPlaybackSuccess)
            {
                try
                {
                    if (this.player != null)
                    {
                        this.player.Stop();
                    }
                }
                catch (Exception)
                {
                    LogClient.Error("Could not stop the Player");
                }

                LogClient.Error("Could not play the file {0}. EventMode={1}, ExclusiveMode={2}, LoopMode={3}, Shuffle={4}. Exception: {5}. StackTrace: {6}", trackPair.Value.Path, this.eventMode.ToString(), this.exclusiveMode.ToString(), this.LoopMode.ToString(), this.shuffle.ToString(), playbackFailedEventArgs.Message, playbackFailedEventArgs.StackTrace);

                this.PlaybackFailed(this, playbackFailedEventArgs);
            }

            this.OnLoadingTrack(false);

            return(isPlaybackSuccess);
        }
        private async Task <bool> TryPlayAsync(TrackInfo trackInfo)
        {
            bool isPlaybackSuccess = true;
            PlaybackFailedEventArgs playbackFailedEventArgs = null;

            if (this.isLoadingTrack)
            {
                return(isPlaybackSuccess);
            }

            this.isLoadingTrack = true;
            this.LoadingTrack(this.isLoadingTrack);

            try
            {
                // If a Track was playing, make sure it is now stopped
                if (this.player != null)
                {
                    // Remove the previous Stopped handler (not sure this is needed)
                    this.player.PlaybackInterrupted -= this.PlaybackInterruptedHandler;
                    this.player.PlaybackFinished    -= this.PlaybackFinishedHandler;

                    this.player.Stop();
                    this.player.Dispose();
                    this.player = null;
                }

                // Check that the file exists
                if (!System.IO.File.Exists(trackInfo.Path))
                {
                    throw new FileNotFoundException(string.Format("File '{0}' was not found", trackInfo.Path));
                }

                // Play the Track from its runtime path (current or temporary)
                this.player = this.playerFactory.Create(Path.GetExtension(trackInfo.Path));

                this.player.SetOutputDevice(this.Latency, this.EventMode, this.ExclusiveMode, this.activePreset.Bands);

                this.ToggleMute();

                // We need to set PlayingTrack before trying to play the Track.
                // So if we go into the Catch when trying to play the Track,
                // at least, the next time TryPlayNext is called, it will know that
                // we already tried to play this track and it can find the next Track.
                this.playingTrack = trackInfo;

                // Play the Track
                await Task.Run(() => this.player.Play(trackInfo.Path));

                // Start reporting progress
                this.progressTimer.Start();

                // Hook up the Stopped event
                this.player.PlaybackInterrupted += this.PlaybackInterruptedHandler;
                this.player.PlaybackFinished    += this.PlaybackFinishedHandler;

                // Playing was successful
                this.PlaybackSuccess(this.isPlayingPreviousTrack);

                // Set this to false again after raising the event. It is important to have a correct slide
                // direction for cover art when the next Track is a file from double click in Windows.
                this.isPlayingPreviousTrack = false;
            }
            catch (FileNotFoundException fnfex)
            {
                playbackFailedEventArgs = new PlaybackFailedEventArgs {
                    FailureReason = PlaybackFailureReason.FileNotFound, Message = fnfex.Message, StackTrace = fnfex.StackTrace
                };
                isPlaybackSuccess = false;
            }
            catch (Exception ex)
            {
                playbackFailedEventArgs = new PlaybackFailedEventArgs {
                    FailureReason = PlaybackFailureReason.Unknown, Message = ex.Message, StackTrace = ex.StackTrace
                };
                isPlaybackSuccess = false;
            }

            if (!isPlaybackSuccess)
            {
                try
                {
                    if (this.player != null)
                    {
                        this.player.Stop();
                    }
                }
                catch (Exception)
                {
                    LogClient.Instance.Logger.Error("Could not stop the Player");
                }

                LogClient.Instance.Logger.Error("Could not play the file {0}. EventMode={1}, ExclusiveMode={2}, LoopMode={3}, Shuffle={4}. Exception: {5}. StackTrace: {6}", trackInfo.Path, this.eventMode, this.exclusiveMode, this.LoopMode.ToString(), this.shuffle, playbackFailedEventArgs.Message, playbackFailedEventArgs.StackTrace);

                this.PlaybackFailed(this, playbackFailedEventArgs);
            }

            this.isLoadingTrack = false;
            this.LoadingTrack(this.isLoadingTrack);

            return(isPlaybackSuccess);
        }