private bool TryGetEducationOrganizationValueMaps(string context, out EducationOrganizationValueMaps identityValueMaps)
        {
            object educationOrganizationCacheAsObject;

            string cacheKey = GetEducationOrganizationCacheKey(context);

            if (!_cacheProvider.TryGetCachedObject(cacheKey, out educationOrganizationCacheAsObject))
            {
                // Make sure there is only one cache set being initialized at a time
                lock (_identityValueMapsLock)
                {
                    // Make sure that the entry still doesn't exist yet
                    if (!_cacheProvider.TryGetCachedObject(cacheKey, out educationOrganizationCacheAsObject))
                    {
                        var newValueMaps = new EducationOrganizationValueMaps();

                        //Put the initialization task on the cached object so that we know the initialization status by cache entry key
                        //Even if/when the cache provider storage changes context
                        newValueMaps.InitializationTask = InitializeEducationOrganizationValueMaps(newValueMaps, context);

                        //Initial Insert is for while async initialization is running.
                        _cacheProvider.Insert(cacheKey, newValueMaps, DateTime.MaxValue, TimeSpan.FromMinutes(5));

                        _cacheProvider.TryGetCachedObject(cacheKey, out educationOrganizationCacheAsObject);
                    }
                }
            }

            identityValueMaps = educationOrganizationCacheAsObject as EducationOrganizationValueMaps;

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

            if (_synchronousInitialization &&
                (identityValueMaps.EducationOrganizationIdentifiersByEducationOrganizationId == null ||
                 identityValueMaps.EducationOrganizationIdentifiersByStateOrganizationId == null))
            {
                // Wait for the initialization task to complete
                identityValueMaps.InitializationTask.WaitSafely();

                //If initialization failed, return false.
                if (identityValueMaps.EducationOrganizationIdentifiersByEducationOrganizationId == null ||
                    identityValueMaps.EducationOrganizationIdentifiersByStateOrganizationId == null)
                {
                    return(false);
                }

                // With initialization complete, try again (using a single recursive call)
                return(TryGetEducationOrganizationValueMaps(context, out identityValueMaps));
            }

            return(true);
        }
        private Task InitializeEducationOrganizationValueMaps(EducationOrganizationValueMaps entry, string context)
        {
            // In web application scenarios, copy pertinent context from HttpContext to CallContext
            if (HttpContextStorageTransfer != null)
            {
                HttpContextStorageTransfer.TransferContext();
            }

            var task = InitializeEducationOrganizationValueMapsAsync(entry, context);

            if (task.Status == TaskStatus.Created)
            {
                task.Start();
            }

            return(task);
        }
        private async Task InitializeEducationOrganizationValueMapsAsync(EducationOrganizationValueMaps entry, string context)
        {
            // Unhandled exceptions here will take down the ASP.NET process
            try
            {
                // Start building the data
                var educationOrganizationIdentifiersByStateOrganizationId =
                    new ConcurrentDictionary <string, EducationOrganizationIdentifiers>();

                var educationOrganizationIdentifiersByEducationOrganizationId =
                    new ConcurrentDictionary <string, EducationOrganizationIdentifiers>();

                Stopwatch stopwatch = null;

                if (_logger.IsDebugEnabled)
                {
                    stopwatch = new Stopwatch();
                    stopwatch.Start();
                }

                foreach (
                    var valueMap in
                    await
                    _educationOrganizationIdentifiersProvider.GetAllEducationOrganizationIdentifiers()
                    .ConfigureAwait(false))
                {
                    string key =
                        GetEducationOrganizationIdentifiersByEducationOrganizationIdCacheKey(
                            valueMap.EducationOrganizationId,
                            context);

                    educationOrganizationIdentifiersByEducationOrganizationId.TryAdd(key, valueMap);

                    //NOTE: future support for string based state org ids.
                    //string key2 = GetEducationOrganizationIdentifiersByStateOrganizationIdCacheKey(valueMap.StateOrganizationId, context);
                    //educationOrganizationIdentifiersByStateOrganizationId.TryAdd(key2, valueMap);
                }

                if (_logger.IsDebugEnabled)
                {
                    stopwatch.Stop();

                    _logger.DebugFormat(
                        "Education Organization Id cache initialized {0:n0} entries in {1:n0} milliseconds.",
                        educationOrganizationIdentifiersByEducationOrganizationId.Count,
                        stopwatch.ElapsedMilliseconds);
                }

                entry.SetMaps(
                    educationOrganizationIdentifiersByStateOrganizationId,
                    educationOrganizationIdentifiersByEducationOrganizationId);

                string cacheKey = GetEducationOrganizationCacheKey(context);

                //Now that it's loaded extend the cache expiration.
                _cacheProvider.Insert(cacheKey, entry, DateTime.MaxValue, TimeSpan.FromHours(4));
            }
            catch (Exception ex)
            {
                _logger.ErrorFormat(
                    "An exception occurred while trying to warm the EducationOrganizationCache. EducationOrganizationIdentifiers will be retrieved individually.\r\n{0}",
                    ex);
            }
        }