protected override async Task ResolveAsync(CancellationToken cancellationToken) { try { var elapsedTimeSinceLastRefresh = SystemClock.UtcNow - _lastResolveStart; if (elapsedTimeSinceLastRefresh < MinimumDnsResolutionRate) { var delay = MinimumDnsResolutionRate - elapsedTimeSinceLastRefresh; DnsResolverLog.StartingRateLimitDelay(_logger, delay, MinimumDnsResolutionRate); await Task.Delay(delay, cancellationToken).ConfigureAwait(false); } var lastResolveStart = SystemClock.UtcNow; if (string.IsNullOrEmpty(_dnsAddress)) { throw new InvalidOperationException($"Resolver address '{_originalAddress}' is not valid. Please use dns:/// for DNS provider."); } DnsResolverLog.StartingDnsQuery(_logger, _dnsAddress); var addresses = #if NET6_0_OR_GREATER await Dns.GetHostAddressesAsync(_dnsAddress, cancellationToken).ConfigureAwait(false); #else await Dns.GetHostAddressesAsync(_dnsAddress).ConfigureAwait(false); #endif DnsResolverLog.ReceivedDnsResults(_logger, addresses.Length, _dnsAddress, addresses); var endpoints = addresses.Select(a => new BalancerAddress(a.ToString(), _port)).ToArray(); var resolverResult = ResolverResult.ForResult(endpoints); Listener(resolverResult); // Only update last resolve start if successful. Backoff will handle limiting resolves on failure. _lastResolveStart = lastResolveStart; } catch (Exception ex) { var message = $"Error getting DNS hosts for address '{_dnsAddress}'."; DnsResolverLog.ErrorQueryingDns(_logger, _dnsAddress, ex); Listener(ResolverResult.ForFailure(GrpcProtocolHelpers.CreateStatusFromException(message, ex, StatusCode.Unavailable))); } }