/// <summary>
 ///     Triggers the <see cref="InactivePlayer"/> event asynchronously.
 /// </summary>
 /// <param name="eventArgs">the event arguments</param>
 /// <returns>a task that represents the asynchronous operation</returns>
 protected virtual Task OnInactivePlayerAsync(InactivePlayerEventArgs eventArgs)
 => InactivePlayer.InvokeAsync(this, eventArgs);
        /// <summary>
        ///     Force polls tracking of all inactive players asynchronously.
        /// </summary>
        /// <returns>a task that represents the asynchronous operation</returns>
        /// <exception cref="ObjectDisposedException">thrown if the instance is disposed</exception>
        public virtual async Task PollAsync()
        {
            EnsureNotDisposed();

            // get all created player instances in the audio service
            var players = _audioService.GetPlayers <LavalinkPlayer>();

            // iterate through players that are connected to a voice channel
            foreach (var player in players.Where(s => s.VoiceChannelId.HasValue))
            {
                // check if the player is inactive
                if (await IsInactiveAsync(player))
                {
                    // add the player to tracking list
                    if (!_players.ContainsKey(player.GuildId))
                    {
                        // mark as tracked
                        _players.Add(player.GuildId, DateTimeOffset.UtcNow + _options.DisconnectDelay);

                        _logger.Log(this, string.Format("Tracked player {0} as inactive.", player.GuildId), LogLevel.Debug);

                        // trigger event
                        await OnPlayerTrackingStatusUpdated(new PlayerTrackingStatusUpdateEventArgs(_audioService,
                                                                                                    player, InactivityTrackingStatus.Tracked));
                    }
                }
                else
                {
                    // the player is active again, remove from tracking list
                    if (_players.Remove(player.GuildId))
                    {
                        _logger.Log(this, string.Format("Removed player {0} from tracking list.", player.GuildId), LogLevel.Debug);

                        // remove from tracking list
                        await UntrackPlayerAsync(player);
                    }
                }
            }

            // remove all inactive, tracked players where the disconnect delay was exceeded
            foreach (var player in _players.ToArray())
            {
                // check if player is inactive and the delay was exceeded
                if (player.Value < DateTimeOffset.UtcNow)
                {
                    var trackedPlayer = _audioService.GetPlayer <LavalinkPlayer>(player.Key);

                    // player does not exists, remove it from the tracking list and continue.
                    if (trackedPlayer is null)
                    {
                        // remove from tracking list
                        await UntrackPlayerAsync(trackedPlayer);

                        continue;
                    }

                    // trigger event
                    var eventArgs = new InactivePlayerEventArgs(_audioService, trackedPlayer);
                    await OnInactivePlayerAsync(eventArgs);

                    // it is wanted that the player should not stop.
                    if (!eventArgs.ShouldStop)
                    {
                        continue;
                    }

                    _logger.Log(this, string.Format("Destroyed player {0} due inactivity.", player.Key), LogLevel.Debug);

                    // dispose the player
                    trackedPlayer.Dispose();

                    // remove from tracking list
                    await UntrackPlayerAsync(trackedPlayer);
                }
            }
        }