private async Task <bool> PollAsync([CallerMemberName] string callerMemberName = nameof(PollAsync))
        {
            DisposeGuard();
            await _pollSemaphore.WaitAsync();

            var result = false;

            try
            {
                OnPollStarted(ServiceConnectionEventArgs.Ok(callerMemberName));

                var serverAlive = await CheckIfServerAliveAsync();

                if (!serverAlive)
                {
                    LastUpdate = DateTime.Now;
                    OnPollFinished(ServiceConnectionEventArgs.Error("Server is down."));
                    return(false);
                }

                var tokenRefreshSuccess = await RefreshTokenAsync();

                if (tokenRefreshSuccess)
                {
                    try
                    {
                        result |= await RefreshPlayersListAsync();

                        result |= await RefreshMatchesListAsync();

                        result |= await RefreshCurrentMatchAsync();
                    }
                    catch (Exception e)
                    {
                        LastUpdate = DateTime.Now;
                        OnPollFinished(ServiceConnectionEventArgs.Error(e, callerMemberName));
                        return(result);
                    }
                }

                LastUpdate = DateTime.Now;
                TryEndInvoke();
                OnPollFinished(ServiceConnectionEventArgs.Ok(callerMemberName: callerMemberName));
            }
            catch (Exception e)
            {
                OnBackgroundError(ServiceConnectionEventArgs.Error(e, callerMemberName));
            }
            finally
            {
                _pollSemaphore.Release();
            }

            return(result);
        }
        private async void TokenRefreshTimerOnElapsed(object sender, ElapsedEventArgs e)
        {
            DisposeGuard();

            try
            {
                await RefreshTokenAsync();
            }
            catch (Exception exception)
            {
                OnBackgroundError(ServiceConnectionEventArgs.Error(exception));
            }

            _tokenRefreshTimer.Start();
        }
        private async Task <bool> CheckIfServerAliveAsync()
        {
            DisposeGuard();

            try
            {
                await _client.GetVersionAsync();
            }
            catch (Exception e)
            {
                OnBackgroundError(ServiceConnectionEventArgs.Error(e));
                return(false);
            }

            return(true);
        }
        private async Task <bool> RefreshCurrentMatchAsync()
        {
            DisposeGuard();

            if (IsAnonymous)
            {
                if (CurrentGame == null)
                {
                    return(false);
                }

                CurrentGame = null;
            }

            if (CurrentGame == null)
            {
                return(false);
            }

            ChessGameDetails match;

            try
            {
                match = await _client.GetMatchAsync(_loginResult?.TokenString, CurrentGame.Id);
            }
            catch (Exception e)
            {
                OnBackgroundError(ServiceConnectionEventArgs.Error(e));
                return(false);
            }

            if (match.Equals(CurrentGame))
            {
                return(false);
            }

            CurrentGame = match;
            return(true);
        }
        /// <summary>
        /// Sends a move in to the currently selected game.
        /// </summary>
        /// <typeparam name="T">Type of the move.</typeparam>
        /// <param name="move">The move.</param>
        /// <returns>True if successful. Otherwise false.</returns>
        public async Task <bool> SendMoveAsync <T>(T move) where T : BaseMove
        {
            DisposeGuard();

            if (CurrentGame == null)
            {
                return(false);
            }

            if (!TryBeginInvoke())
            {
                return(false);
            }

            bool result;

            try
            {
                result = await _client.SendMoveAsync(_loginResult?.TokenString, CurrentGame.Id, move);
            }
            catch (Exception e)
            {
                TryEndInvoke();
                OnPollFinished(ServiceConnectionEventArgs.Error(e));
                return(false);
            }

            if (result)
            {
                await PollAsync();
            }

            TryEndInvoke();

            return(result);
        }
 private void OnBackgroundError(ServiceConnectionEventArgs e)
 {
     BackgroundError?.Invoke(this, e);
 }
 private void OnPollFinished(ServiceConnectionEventArgs e)
 {
     PollFinished?.Invoke(this, e);
     LastUpdate = DateTime.Now;
 }
 private void OnPollStarted(ServiceConnectionEventArgs e)
 {
     PollStarted?.Invoke(this, e);
 }