void EnsureInit(string configKey) {
bool doInit = false;
lock (this) {
// If the user config is not initialized, then we must either:
// a. Perform the initialization ourselves if no other thread is doing it, or
// b. Wait for the initialization to complete if we know the section is not used during initialization itself, or
// c. Ignore initialization if the section can be used during initialization. Note that GetSection()
// returns null is initialization has not completed.
if (!_isUserConfigInited) {
if (!_isInitInProgress) {
_isInitInProgress = true;
doInit = true;
}
else if (!IsSectionUsedInInit(configKey)) {
// Wait for initialization to complete.
Monitor.Wait(this);
}
}
}
if (doInit) {
try {
try {
try {
// Initialize machine configuration.
_machineConfigRecord = _configRoot.GetConfigRecord(
ClientConfigurationHost.MachineConfigPath);
_machineConfigRecord.ThrowIfInitErrors();
// Make machine configuration available to system.net sections
// when application configuration is downloaded via http.
_isMachineConfigInited = true;
//
// Prevent deadlocks in the networking classes by loading
// networking config before making a networking request.
// Any requests for sections used in initialization during
// the call to EnsureConfigLoaded() will be served by
// _machine.config or will return null.
//
if (_isAppConfigHttp) {
ConfigurationManagerHelperFactory.Instance.EnsureNetConfigLoaded();
}
//
// Now load the rest of configuration
//
_configHost.RefreshConfigPaths();
string configPath;
if (_configHost.HasLocalConfig) {
configPath = ClientConfigurationHost.LocalUserConfigPath;
}
else if (_configHost.HasRoamingConfig) {
configPath = ClientConfigurationHost.RoamingUserConfigPath;
}
else {
configPath = ClientConfigurationHost.ExeConfigPath;
}
_completeConfigRecord = _configRoot.GetConfigRecord(configPath);
_completeConfigRecord.ThrowIfInitErrors();
_isUserConfigInited = true;
}
catch (Exception e) {
_initError = new ConfigurationErrorsException(SR.GetString(SR.Config_client_config_init_error), e);
throw _initError;
}
catch {
_initError = new ConfigurationErrorsException(SR.GetString(SR.Config_client_config_init_error));
throw _initError;
}
}
catch {
ConfigurationManager.SetInitError(_initError);
_isMachineConfigInited = true;
_isUserConfigInited = true;
throw;
}
}
finally {
lock (this) {
try {
// Notify ConfigurationSettings that initialization has fully completed,
// even if unsuccessful.
ConfigurationManager.CompleteConfigInit();
_isInitInProgress = false;
}
finally {
// Wake up all threads waiting for initialization to complete.
Monitor.PulseAll(this);
}
}
}
}
}