public async Task <PingDataPoint> PingServerAsync(PingSetting setting) { using (var httpClient = _factory.BuildClient()) { TimeSpan responseTime; HttpStatusCode statusCode = HttpStatusCode.ServiceUnavailable; // Generate a request var httpContent = new HttpRequestMessage( setting.GetMethodRequired ? HttpMethod.Get : HttpMethod.Head, setting.ServerUrl ); var timer = new Stopwatch(); timer.Start(); var task = httpClient.SendAsync(httpContent); // Make sure task finishes in TotalMilliseconds milliseconds if ( await Task.WhenAny( task, Task.Delay(Convert.ToInt32(setting.MaxResponseTime.TotalMilliseconds)) ) == task ) { var response = await task; timer.Stop(); // Record time and code responseTime = timer.Elapsed; statusCode = response.StatusCode; } if ( statusCode == HttpStatusCode.ServiceUnavailable || responseTime > setting.MaxResponseTime ) { // Timeout/cancellation logic // If problem occurred then set service unavailable. responseTime = new TimeSpan(0); statusCode = HttpStatusCode.ServiceUnavailable; // _logger.LogWarning(LoggingEvents.Ping.AsInt(), $"Resource {setting.ServerUrl} is unavailable. See stack trace."); } _logger.LogDebug(LoggingEvents.Ping.AsInt(), $"Ping completed for {setting.ServerUrl}"); var metric = await _metrics.GetOrCreateMetricAsync(Metrics.Ping, new Uri(setting.ServerUrl).Host); return(new PingDataPoint { Metric = metric, ResponseTime = responseTime, Success = statusCode.AsInt() / 100 == 2, // 2xx Message = statusCode.AsInt() / 100 == 2 ? "OK" : "Failure" }); } }