/// <summary>
        /// Create the singleton instance for the RDX C# client SDK
        /// Deletes singleton if the access to the specified environment fails
        /// to prevent subsequent access of worker threads
        /// </summary>
        public static async void Create()
        {
            while (true)
            {
                RDXTrace.TraceInformation("Start RDX Query Client");

                try
                {
                    ServicePointManager.DefaultConnectionLimit = 1000;
                    CommonLogger.SetWriter(TraceLogWriter.Instance);

                    // Authenticate with the RDX service, depending on configuration one option is used
                    // to create the OAuth2 bearer tokens
                    IClientAuthenticator clientAuthenticator;
                    string    tenantId = ConfigurationProvider.GetConfigurationSettingValue(rdxAuthenticationTenantId);
                    IccString clientCertificateThumbprint = new IccString(ConfigurationProvider.GetConfigurationSettingValue(rdxAuthenticationClientCertificateThumbprint));
                    if (clientCertificateThumbprint.IsNullOrWhiteSpace())
                    {
                        string clientId     = ConfigurationProvider.GetConfigurationSettingValue(rdxAuthenticationClientId);
                        string clientSecret = ConfigurationProvider.GetConfigurationSettingValue(rdxAuthenticationClientSecret);
                        if (String.IsNullOrWhiteSpace(clientSecret))
                        {
                            Uri redirectUri = new Uri(ConfigurationProvider.GetConfigurationSettingValue(rdxAuthenticationRedirectUri));
                            clientAuthenticator = new UserClientAuthenticator(tenantId, clientId, redirectUri, BaseClientAuthenticator.AzureTimeSeriesResource);
                        }
                        else
                        {
                            clientAuthenticator = new ClientCredentialAuthenticator(tenantId, clientId, clientSecret, BaseClientAuthenticator.AzureTimeSeriesResource);
                        }
                    }
                    else
                    {
                        string applicationClientId = ConfigurationProvider.GetConfigurationSettingValue(rdxAuthenticationClientApplicationId);
                        clientAuthenticator = new ApplicationCertificateClientAuthenticator(applicationClientId, clientCertificateThumbprint, tenantId, BaseClientAuthenticator.AzureTimeSeriesResource);
                    }

                    // Create the RDX client with authenticator and DNS resolver
                    _rdxDNSName = ConfigurationProvider.GetConfigurationSettingValue(rdxDnsName);
                    IccString rdxIccDnsName = new IccString("api." + _rdxDNSName);
                    string    solutionName  = ConfigurationProvider.GetConfigurationSettingValue(rdxApplicationName);
                    _rdxGlobalQueryClient = new RdxGlobalQueryClient(rdxIccDnsName, solutionName, clientAuthenticator);

                    // Test if our environment exists and is accessible
                    _rdxEnvironmentId = new IccString(ConfigurationProvider.GetConfigurationSettingValue(rdxEnvironmentId));
                    GetEnvironmentsOutput environments = await GetEnvironmentsAsync(CancellationToken.None);

                    Trace.TraceInformation("Got {0} environments: ", environments.Environments.Count);
                    bool foundEnvironment = false;
                    foreach (var env in environments.Environments)
                    {
                        Trace.TraceInformation("  {0} {1}", env.EnvironmentId, env.DisplayName);
                        if (env.EnvironmentId == _rdxEnvironmentId)
                        {
                            foundEnvironment    = true;
                            _rdxEnvironmentName = env.DisplayName;
                            _rdxEnvironmentFqdn = env.EnvironmentFqdn;
                            break;
                        }
                    }

                    if (!foundEnvironment)
                    {
                        throw new Exception(String.Format("RDX Environment {0} not found.", _rdxEnvironmentId.ToString()));
                    }

                    _rdxEnvironmentQueryClient = new RdxEnvironmentQueryClient(
                        _rdxEnvironmentFqdn,
                        solutionName,
                        clientAuthenticator);

                    Trace.TraceInformation("..... RDXQueryClient started .....");

                    return;
                }
                catch (Exception e)
                {
                    RDXTrace.TraceError("RDX CreateQueryClient failed: {0}", e.ExceptionToString());
                    _rdxGlobalQueryClient      = null;
                    _rdxEnvironmentQueryClient = null;
                }

                RDXTrace.TraceError("Fatal: RDX environment not found. Retry in 60s.");
                await Task.Delay(60000);
            }
        }