/// <summary> /// Asynchronously gets a <see cref="ITeamCompetitor" /> representing away competitor of the match associated with the current instance /// </summary> /// <returns>A <see cref="Task{ITeamCompetitor}"/> representing the retrieval operation</returns> public async Task <ITeamCompetitor> GetAwayCompetitorAsync() { var matchCI = (IMatchCI)SportEventCache.GetEventCacheItem(Id); if (matchCI == null) { ExecutionLog.LogDebug($"Missing data. No match cache item for id={Id}."); return(null); } var items = ExceptionStrategy == ExceptionHandlingStrategy.THROW ? await matchCI.GetCompetitorsAsync(Cultures).ConfigureAwait(false) : await new Func <IEnumerable <CultureInfo>, Task <IEnumerable <URN> > >(matchCI.GetCompetitorsAsync).SafeInvokeAsync(Cultures, ExecutionLog, GetFetchErrorMessage("Competitors")).ConfigureAwait(false); if (items == null) { return(null); } var competitorUrns = items.ToList(); if (competitorUrns.Count == 2) { return(await _sportEntityFactory.BuildTeamCompetitorAsync(competitorUrns[1], Cultures, matchCI).ConfigureAwait(false)); } ExecutionLog.LogError($"Received {competitorUrns.Count} competitors for match[Id = {Id}]. Match can have only 2 competitors."); throw new InvalidOperationException($"Invalid number of competitors. Match must have exactly 2 competitors, received {competitorUrns.Count}"); }
/// <summary> /// Asynchronously gets the associated category /// </summary> /// <returns>The associated category</returns> public async Task <ICategorySummary> GetCategoryAsync() { var lotteryCI = (LotteryCI)SportEventCache.GetEventCacheItem(Id); if (lotteryCI == null) { ExecutionLog.LogDebug($"Missing data. No lottery cache item for id={Id}."); return(null); } var categoryId = ExceptionStrategy == ExceptionHandlingStrategy.THROW ? await lotteryCI.GetCategoryIdAsync().ConfigureAwait(false) : await new Func <Task <URN> >(lotteryCI.GetCategoryIdAsync).SafeInvokeAsync(ExecutionLog, GetFetchErrorMessage("CategoryId")).ConfigureAwait(false); if (categoryId == null) { ExecutionLog.LogDebug($"Missing data. No categoryId for lottery cache item with id={Id}."); return(null); } var categoryData = ExceptionStrategy == ExceptionHandlingStrategy.THROW ? await _sportDataCache.GetCategoryAsync(categoryId, Cultures).ConfigureAwait(false) : await new Func <URN, IEnumerable <CultureInfo>, Task <CategoryData> >(_sportDataCache.GetCategoryAsync).SafeInvokeAsync(categoryId, Cultures, ExecutionLog, GetFetchErrorMessage("CategoryData")).ConfigureAwait(false); return(categoryData == null ? null : new CategorySummary(categoryData.Id, categoryData.Names, categoryData.CountryCode)); }
public async Task <IStage> GetParentStageAsync() { var stageCI = (StageCI)SportEventCache.GetEventCacheItem(Id); if (stageCI == null) { ExecutionLog.LogDebug($"Missing data. No stage cache item for id={Id}."); return(null); } var parentStageId = await stageCI.GetParentStageAsync(Cultures).ConfigureAwait(false); if (parentStageId != null) { //var parentStageCI = (StageCI) SportEventCache.GetEventCacheItem(parentStageId); //if (parentStageCI == null) //{ // return new Stage(parentStageId, GetSportAsync().Result.Id, _sportEntityFactory, SportEventCache, _sportDataCache, SportEventStatusCache, _matchStatusesCache, Cultures, ExceptionStrategy); //} return(new Stage(parentStageId, GetSportAsync().Result.Id, _sportEntityFactory, SportEventCache, _sportDataCache, SportEventStatusCache, MatchStatusCache, Cultures, ExceptionStrategy)); } return(null); }
/// <summary> /// Asynchronously gets a <see cref="IEnumerable{T}"/> representing competitors in the sport event associated with the current instance /// </summary> /// <returns>A <see cref="Task{T}"/> representing the retrieval operation</returns> public async Task <IEnumerable <ICompetitor> > GetCompetitorsAsync() { var competitionCI = (CompetitionCI)SportEventCache.GetEventCacheItem(Id); if (competitionCI == null) { ExecutionLog.LogDebug($"Missing data. No sportEvent cache item for id={Id}."); return(null); } var items = ExceptionStrategy == ExceptionHandlingStrategy.THROW ? await competitionCI.GetCompetitorsAsync(Cultures).ConfigureAwait(false) : await new Func <IEnumerable <CultureInfo>, Task <IEnumerable <URN> > >(competitionCI.GetCompetitorsAsync).SafeInvokeAsync(Cultures, ExecutionLog, GetFetchErrorMessage("Competitors")).ConfigureAwait(false); var competitorUrns = items as List <URN>; if (competitorUrns == null || !competitorUrns.Any()) { return(null); } var tasks = competitorUrns.Select(s => { var t = _sportEntityFactory.BuildTeamCompetitorAsync(s, Cultures, competitionCI); t.ConfigureAwait(false); return(t); }).ToList(); await Task.WhenAll(tasks).ConfigureAwait(false); return(tasks.Select(s => s.Result)); }
public async Task <StageType?> GetStageTypeAsync() { var stageCI = (StageCI)SportEventCache.GetEventCacheItem(Id); if (stageCI == null) { ExecutionLog.LogDebug($"Missing data. No stage cache item for id={Id}."); return(StageType.Child); } return(await stageCI.GetStageTypeAsync().ConfigureAwait(false)); }
/// <summary> /// Adds the sport event status to the internal cache /// </summary> /// <param name="eventId">The eventId of the sport event status to be cached</param> /// <param name="sportEventStatus">The sport event status to be cached</param> /// <param name="statusOnEvent">The sport event status received directly on event level</param> /// <param name="source">The source of the SES</param> private void AddSportEventStatus(URN eventId, SportEventStatusCI sportEventStatus, string statusOnEvent, string source) { if (_isDisposed) { return; } if (sportEventStatus == null) { return; } Guard.Argument(eventId, nameof(eventId)).NotNull(); if (string.IsNullOrEmpty(source) || source.Equals("OddsChange", StringComparison.InvariantCultureIgnoreCase) || source.Equals("SportEventSummary", StringComparison.InvariantCultureIgnoreCase) || !_sportEventStatusCache.Contains(eventId.ToString())) { lock (_lock) { if (!string.IsNullOrEmpty(source)) { if (OperationManager.IgnoreBetPalTimelineSportEventStatus && source.Contains("Timeline") && _ignoreEventsTimelineCache.Contains(eventId.ToString())) { ExecutionLog.LogDebug($"Received SES for {eventId} from {source} with EventStatus:{sportEventStatus.Status} (timeline ignored) {statusOnEvent}"); return; } source = $" from {source}"; } ExecutionLog.LogDebug($"Received SES for {eventId}{source} with EventStatus:{sportEventStatus.Status}"); var cacheItem = _sportEventStatusCache.AddOrGetExisting( eventId.ToString(), sportEventStatus, new CacheItemPolicy { AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(OperationManager.SportEventStatusCacheTimeout.TotalSeconds) }) as SportEventStatusCI; if (cacheItem != null) { cacheItem.SetFeedStatus(sportEventStatus.FeedStatusDTO); cacheItem.SetSapiStatus(sportEventStatus.SapiStatusDTO); } } } else { ExecutionLog.LogDebug($"Received SES for {eventId} from {source} with EventStatus:{sportEventStatus.Status} (ignored)"); } }
/// <summary> /// Asynchronously gets a <see cref="IFixture"/> instance containing information about the arranged sport event /// </summary> /// <returns>A <see cref="Task{IFixture}"/> representing the retrieval operation</returns> /// <remarks>A Fixture is a sport event that has been arranged for a particular time and place</remarks> public async Task <IFixture> GetFixtureAsync() { var matchCI = (IMatchCI)SportEventCache.GetEventCacheItem(Id); if (matchCI == null) { ExecutionLog.LogDebug($"Missing data. No match cache item for id={Id}."); return(null); } return(ExceptionStrategy == ExceptionHandlingStrategy.THROW ? await matchCI.GetFixtureAsync(Cultures).ConfigureAwait(false) : await new Func <IEnumerable <CultureInfo>, Task <IFixture> >(matchCI.GetFixtureAsync).SafeInvokeAsync(Cultures, ExecutionLog, GetFetchErrorMessage("Fixture")).ConfigureAwait(false)); }
/// <summary> /// Asynchronously gets a <see cref="BookingStatus"/> enum member providing booking status for the associated @event or a null reference if booking status is not known /// </summary> /// <returns></returns> public async Task <BookingStatus?> GetBookingStatusAsync() { var competitionCI = (CompetitionCI)SportEventCache.GetEventCacheItem(Id); if (competitionCI == null) { ExecutionLog.LogDebug($"Missing data. No sportEvent cache item for id={Id}."); return(null); } return(ExceptionStrategy == ExceptionHandlingStrategy.THROW ? await competitionCI.GetBookingStatusAsync().ConfigureAwait(false) : await new Func <Task <BookingStatus?> >(competitionCI.GetBookingStatusAsync).SafeInvokeAsync(ExecutionLog, GetFetchErrorMessage("BookingStatus")).ConfigureAwait(false)); }
/// <summary> /// Asynchronously gets <see cref="T:System.Collections.Generic.IEnumerable`1" /> list of associated <see cref="T:Sportradar.OddsFeed.SDK.Entities.REST.IDrawResult" /> /// </summary> /// <returns>A <see cref="T:System.Threading.Tasks.Task`1" /> representing an async operation</returns> /// <exception cref="NotImplementedException"></exception> public async Task <IEnumerable <IDrawResult> > GetResultsAsync() { var drawCI = (DrawCI)SportEventCache.GetEventCacheItem(Id); if (drawCI == null) { ExecutionLog.LogDebug($"Missing data. No draw cache item for id={Id}."); return(null); } var item = ExceptionStrategy == ExceptionHandlingStrategy.THROW ? await drawCI.GetResultsAsync(Cultures).ConfigureAwait(false) : await new Func <IEnumerable <CultureInfo>, Task <IEnumerable <DrawResultCI> > >(drawCI.GetResultsAsync).SafeInvokeAsync(Cultures, ExecutionLog, "DrawResults").ConfigureAwait(false); return(item?.Select(s => new DrawResult(s))); }
/// <summary> /// Asynchronously gets the list of associated <see cref="IDraw"/> /// </summary> /// <returns>A <see cref="Task{T}"/> representing an async operation</returns> public async Task <IEnumerable <IDraw> > GetDrawsAsync() { var lotteryCI = (LotteryCI)SportEventCache.GetEventCacheItem(Id); if (lotteryCI == null) { ExecutionLog.LogDebug($"Missing data. No lottery cache item for id={Id}."); return(null); } var item = ExceptionStrategy == ExceptionHandlingStrategy.THROW ? await lotteryCI.GetScheduledDrawsAsync().ConfigureAwait(false) : await new Func <Task <IEnumerable <URN> > >(lotteryCI.GetScheduledDrawsAsync).SafeInvokeAsync(ExecutionLog, GetFetchErrorMessage("ScheduledDraws")).ConfigureAwait(false); return(item.Select(selector: s => new Draw(s, SportId, SportEventCache, Cultures, ExceptionStrategy))); }
/// <summary> /// Asynchronously gets <see cref="DrawStatus" /> associated with the current instance /// </summary> /// <returns>A <see cref="T:System.Threading.Tasks.Task`1" /> representing an async operation</returns> /// <exception cref="NotImplementedException"></exception> public async Task <DrawStatus> GetStatusAsync() { var drawCI = (DrawCI)SportEventCache.GetEventCacheItem(Id); if (drawCI == null) { ExecutionLog.LogDebug($"Missing data. No draw cache item for id={Id}."); return(DrawStatus.Unknown); } var item = ExceptionStrategy == ExceptionHandlingStrategy.THROW ? await drawCI.GetStatusAsync().ConfigureAwait(false) : await new Func <Task <DrawStatus> >(drawCI.GetStatusAsync).SafeInvokeAsync(ExecutionLog, "DrawStatus").ConfigureAwait(false); return(item); }
/// <summary> /// Asynchronously loads the list of market descriptions from the Sports API /// </summary> /// <returns>Returns true if the action succeeded</returns> public async Task <bool> LoadMarketDescriptionsAsync() { try { ExecutionLog.LogDebug($"Loading invariant market descriptions for [{string.Join(",", _prefetchLanguages.Select(l => l.TwoLetterISOLanguageName))}] (user request)."); _fetchedLanguages.Clear(); await GetMarketInternalAsync(0, _prefetchLanguages).ConfigureAwait(false); } catch (Exception ex) { ExecutionLog.LogWarning($"An error occurred while fetching market descriptions. The exception:{ex.Message}"); return(false); } return(true); }
/// <summary> /// Asynchronously gets a liveOdds /// </summary> /// <returns>A liveOdds</returns> public async Task <string> GetLiveOddsAsync() { var competitionCI = (CompetitionCI)SportEventCache.GetEventCacheItem(Id); if (competitionCI == null) { ExecutionLog.LogDebug($"Missing data. No match cache item for id={Id}."); return(null); } var liveOdds = ExceptionStrategy == ExceptionHandlingStrategy.THROW ? await competitionCI.GetLiveOddsAsync().ConfigureAwait(false) : await new Func <Task <string> >(competitionCI.GetLiveOddsAsync).SafeInvokeAsync(ExecutionLog, GetFetchErrorMessage("LiveOdds")).ConfigureAwait(false); return(liveOdds); }
/// <summary> /// Asynchronously gets a list of additional ids of the parent stages of the current instance or a null reference if the represented stage does not have the parent stages /// </summary> /// <returns>A <see cref="Task{StageCI}"/> representing the asynchronous operation</returns> public async Task <IEnumerable <IStage> > GetAdditionalParentStagesAsync() { var stageCI = (StageCI)SportEventCache.GetEventCacheItem(Id); if (stageCI == null) { ExecutionLog.LogDebug($"Missing data. No stage cache item for id={Id}."); return(null); } var cacheItems = ExceptionStrategy == ExceptionHandlingStrategy.THROW ? await stageCI.GetAdditionalParentStagesAsync(Cultures).ConfigureAwait(false) : await new Func <IEnumerable <CultureInfo>, Task <IEnumerable <URN> > >(stageCI.GetAdditionalParentStagesAsync) .SafeInvokeAsync(Cultures, ExecutionLog, GetFetchErrorMessage("AdditionalParentStages")).ConfigureAwait(false); return(cacheItems?.Select(c => new Stage(c, GetSportAsync().Result.Id, _sportEntityFactory, SportEventCache, _sportDataCache, SportEventStatusCache, MatchStatusCache, Cultures, ExceptionStrategy))); }
/// <summary> /// Asynchronously gets a <see cref="ISportEventConditions"/> instance representing live conditions of the sport event associated with the current instance /// </summary> /// <returns>A <see cref="Task{IVenue}"/> representing the retrieval operation</returns> /// <remarks>A Fixture is a sport event that has been arranged for a particular time and place</remarks> public async Task <ISportEventConditions> GetConditionsAsync() { var competitionCI = (CompetitionCI)SportEventCache.GetEventCacheItem(Id); if (competitionCI == null) { ExecutionLog.LogDebug($"Missing data. No sportEvent cache item for id={Id}."); return(null); } var item = ExceptionStrategy == ExceptionHandlingStrategy.THROW ? await competitionCI.GetConditionsAsync(Cultures).ConfigureAwait(false) : await new Func <IEnumerable <CultureInfo>, Task <SportEventConditionsCI> >(competitionCI.GetConditionsAsync).SafeInvokeAsync(Cultures, ExecutionLog, GetFetchErrorMessage("EventConditions")).ConfigureAwait(false); return(item == null ? null : new SportEventConditions(item, Cultures)); }
/// <summary> /// Asynchronously gets a <see cref="ILongTermEvent"/> representing the tournament to which the sport event associated with the current instance belongs to /// </summary> /// <returns>A <see cref="Task{ILongTermEvent}"/> representing the retrieval operation</returns> public async Task <ILongTermEvent> GetTournamentAsync() { var matchCI = (IMatchCI)SportEventCache.GetEventCacheItem(Id); if (matchCI == null) { ExecutionLog.LogDebug($"Missing data. No match cache item for id={Id}."); return(null); } var tournamentId = ExceptionStrategy == ExceptionHandlingStrategy.THROW ? await matchCI.GetTournamentIdAsync().ConfigureAwait(false) : await new Func <Task <URN> >(matchCI.GetTournamentIdAsync).SafeInvokeAsync(ExecutionLog, GetFetchErrorMessage("ILongTermEvent")).ConfigureAwait(false); return(tournamentId == null ? null : _sportEntityFactory.BuildSportEvent <ILongTermEvent>(tournamentId, null, Cultures, ExceptionStrategy)); }
/// <summary> /// Asynchronously gets <see cref="IDrawInfo"/> associated with the current instance /// </summary> /// <returns>A <see cref="Task{T}"/> representing an async operation</returns> public async Task <IDrawInfo> GetDrawInfoAsync() { var lotteryCI = (LotteryCI)SportEventCache.GetEventCacheItem(Id); if (lotteryCI == null) { ExecutionLog.LogDebug($"Missing data. No lottery cache item for id={Id}."); return(null); } var item = ExceptionStrategy == ExceptionHandlingStrategy.THROW ? await lotteryCI.GetDrawInfoAsync().ConfigureAwait(false) : await new Func <Task <DrawInfoCI> >(lotteryCI.GetDrawInfoAsync).SafeInvokeAsync(ExecutionLog, GetFetchErrorMessage("DrawInfo")).ConfigureAwait(false); return(item == null ? null : new DrawInfo(item)); }
/// <summary> /// Invoked when the <code>_timer</code> ticks in order to periodically fetch market descriptions for configured languages /// </summary> /// <param name="sender">The <see cref="ITimer"/> raising the event</param> /// <param name="e">A <see cref="EventArgs"/> instance containing the event data</param> private async void OnTimerElapsed(object sender, EventArgs e) { if (_isDisposed) { return; } //when the timer first elapses fetch data only for languages which were not yet fetched. On subsequent timer elapses fetch data for all configured languages var languagesToFetch = _prefetchLanguages.Where(language => !_fetchedLanguages.Contains(language) || _hasTimerElapsedOnce).ToList(); if (!languagesToFetch.Any()) { _hasTimerElapsedOnce = true; return; } try { _fetchedLanguages.Clear(); ExecutionLog.LogDebug($"Loading invariant market descriptions for [{string.Join(",", languagesToFetch.Select(l => l.TwoLetterISOLanguageName))}] (timer)."); await GetMarketInternalAsync(0, languagesToFetch).ConfigureAwait(false); } catch (Exception ex) { if (ex is CommunicationException || ex is DeserializationException || ex is FormatException) { var languagesString = string.Join(",", languagesToFetch.Select(l => l.TwoLetterISOLanguageName)); ExecutionLog.LogWarning($"An error occurred while periodically fetching market description of languages {languagesString}", ex); return; } var disposedException = ex as ObjectDisposedException; if (disposedException != null) { ExecutionLog.LogWarning($"An error occurred while periodically fetching market descriptions because the object graph is being disposed. Object causing the exception:{disposedException.ObjectName}"); return; } if (ex is TaskCanceledException) { ExecutionLog.LogWarning("An error occurred while periodically fetching market descriptions because the object graph is being disposed."); return; } ExecutionLog.LogWarning("An error occurred while periodically fetching market description.", ex); } _hasTimerElapsedOnce = true; }
public async Task <IStage> GetParentStageAsync() { var stageCI = (StageCI)SportEventCache.GetEventCacheItem(Id); if (stageCI == null) { ExecutionLog.LogDebug($"Missing data. No stage cache item for id={Id}."); return(null); } var cacheItem = ExceptionStrategy == ExceptionHandlingStrategy.CATCH ? await stageCI.GetParentStageAsync(Cultures).ConfigureAwait(false) : await new Func <IEnumerable <CultureInfo>, Task <StageCI> >(stageCI.GetParentStageAsync) .SafeInvokeAsync(Cultures, ExecutionLog, GetFetchErrorMessage("ParentStage")).ConfigureAwait(false); return(cacheItem == null ? null : new Stage(cacheItem.Id, GetSportAsync().Result.Id, _sportEntityFactory, SportEventCache, _sportDataCache, SportEventStatusCache, _matchStatusesCache, Cultures, ExceptionStrategy)); }
/// <summary> /// Gets the associated event timeline /// </summary> /// <returns>A <see cref="T:System.Threading.Tasks.Task`1" /> representing the retrieval operation</returns> public async Task <IEventTimeline> GetEventTimelineAsync() { var matchCI = (IMatchCI)SportEventCache.GetEventCacheItem(Id); if (matchCI == null) { ExecutionLog.LogDebug($"Missing data. No match cache item for id={Id}."); return(null); } //var oneCulture = new List<CultureInfo> {Cultures.First()}; var eventTimelineCI = ExceptionStrategy == ExceptionHandlingStrategy.THROW ? await matchCI.GetEventTimelineAsync(Cultures).ConfigureAwait(false) : await new Func <IEnumerable <CultureInfo>, Task <EventTimelineCI> >(matchCI.GetEventTimelineAsync).SafeInvokeAsync(Cultures, ExecutionLog, GetFetchErrorMessage("EventTimeline")).ConfigureAwait(false); return(eventTimelineCI == null ? null : new EventTimeline(eventTimelineCI)); }
public async Task <ISportSummary> GetSportAsync() { var stageCI = (StageCI)SportEventCache.GetEventCacheItem(Id); if (stageCI == null) { ExecutionLog.LogDebug($"Missing data. No stage cache item for id={Id}."); return(null); } var sportId = await stageCI.GetSportIdAsync().ConfigureAwait(false); if (sportId == null) { ExecutionLog.LogDebug($"Missing data. No sportId for stage cache item with id={Id}."); return(null); } var sportCI = await _sportDataCache.GetSportAsync(sportId, Cultures).ConfigureAwait(false); return(sportCI == null ? null : new SportSummary(sportCI.Id, sportCI.Names)); }
public async Task <ICategorySummary> GetCategoryAsync() { var stageCI = (StageCI)SportEventCache.GetEventCacheItem(Id); if (stageCI == null) { ExecutionLog.LogDebug($"Missing data. No stage cache item for id={Id}."); return(null); } var categoryId = await stageCI.GetCategoryIdAsync(Cultures).ConfigureAwait(false); if (categoryId == null) { ExecutionLog.LogDebug($"Missing data. No categoryId for stage cache item with id={Id}."); return(null); } var categoryCI = await _sportDataCache.GetCategoryAsync(categoryId, Cultures).ConfigureAwait(false); return(categoryCI == null ? null : new CategorySummary(categoryCI.Id, categoryCI.Names, categoryCI.CountryCode)); }
public async Task <PlayerProfileCI> GetPlayerProfileAsync(URN playerId, IEnumerable <CultureInfo> cultures) { Guard.Argument(playerId, nameof(playerId)).NotNull(); Guard.Argument(cultures, nameof(cultures)).NotNull(); if (!cultures.Any()) { throw new ArgumentOutOfRangeException(nameof(cultures)); } var timerOptions = new TimerOptions { Context = "ProfileCache", Name = "GetPlayerProfileAsync", MeasurementUnit = Unit.Requests }; using (SdkMetricsFactory.MetricsRoot.Measure.Timer.Time(timerOptions, $"{playerId}")) { await _semaphorePlayer.WaitAsync().ConfigureAwait(false); PlayerProfileCI cachedItem; try { cachedItem = (PlayerProfileCI)_cache.Get(playerId.ToString()); var wantedCultures = cultures.ToList(); var missingLanguages = LanguageHelper.GetMissingCultures(wantedCultures, cachedItem?.Names.Keys).ToList(); if (!missingLanguages.Any()) { return(cachedItem); } // try to fetch for competitor, to avoid requests by each player if (cachedItem?.CompetitorId != null) { var competitorCI = (CompetitorCI)_cache.Get(cachedItem.CompetitorId.ToString()); if (competitorCI != null && (competitorCI.LastTimeCompetitorProfileFetched < DateTime.Now.AddSeconds(-30) || LanguageHelper.GetMissingCultures(wantedCultures, competitorCI.CultureCompetitorProfileFetched).Any())) { ExecutionLog.LogDebug($"Fetching competitor profile for competitor {competitorCI.Id} instead of player {cachedItem.Id} for languages=[{string.Join(",", missingLanguages.Select(s => s.TwoLetterISOLanguageName))}]."); try { await _semaphoreCompetitor.WaitAsync().ConfigureAwait(false); var cultureTasks = missingLanguages.ToDictionary(c => c, c => _dataRouterManager.GetCompetitorAsync(competitorCI.Id, c, null)); await Task.WhenAll(cultureTasks.Values).ConfigureAwait(false); } catch (Exception) { // ignored } finally { if (!_isDisposed) { _semaphoreCompetitor.Release(); } } cachedItem = (PlayerProfileCI)_cache.Get(playerId.ToString()); missingLanguages = LanguageHelper.GetMissingCultures(wantedCultures, cachedItem?.Names.Keys).ToList(); if (!missingLanguages.Any()) { return(cachedItem); } } } var cultureTaskDictionary = missingLanguages.ToDictionary(c => c, c => _dataRouterManager.GetPlayerProfileAsync(playerId, c, null)); await Task.WhenAll(cultureTaskDictionary.Values).ConfigureAwait(false); cachedItem = (PlayerProfileCI)_cache.Get(playerId.ToString()); } catch (Exception ex) { if (ex is DeserializationException || ex is MappingException) { throw new CacheItemNotFoundException($"An error occurred while fetching player profile for player {playerId} in cache", playerId.ToString(), ex); } throw; } finally { if (!_isDisposed) { _semaphorePlayer.Release(); } } return(cachedItem); } }