private async Task <bool> ExecuteLazyOperationsSingleStep(ResponseTimeInformation responseTimeInformation) { var disposables = pendingLazyOperations.Select(x => x.EnterContext()).Where(x => x != null).ToList(); try { var requests = pendingLazyOperations.Select(x => x.CreateRequest()).ToArray(); var responses = await AsyncDatabaseCommands.MultiGetAsync(requests); for (int i = 0; i < pendingLazyOperations.Count; i++) { long totalTime; long.TryParse(responses[i].Headers["Temp-Request-Time"], out totalTime); responseTimeInformation.DurationBreakdown.Add(new ResponseTimeItem { Url = requests[i].UrlAndQuery, Duration = TimeSpan.FromMilliseconds(totalTime) }); if (responses[i].RequestHasErrors()) { throw new InvalidOperationException("Got an error from server, status code: " + responses[i].Status + Environment.NewLine + responses[i].Result); } pendingLazyOperations[i].HandleResponse(responses[i]); if (pendingLazyOperations[i].RequiresRetry) { return(true); } } return(false); } finally { foreach (var disposable in disposables) { disposable.Dispose(); } } }
public async Task <ResponseTimeInformation> ExecuteAllPendingLazyOperationsAsync(CancellationToken token = default(CancellationToken)) { if (pendingLazyOperations.Count == 0) { return(new ResponseTimeInformation()); } try { var sw = Stopwatch.StartNew(); IncrementRequestCount(); var responseTimeDuration = new ResponseTimeInformation(); while (await ExecuteLazyOperationsSingleStep(responseTimeDuration).WithCancellation(token).ConfigureAwait(false)) { await Task.Delay(100).WithCancellation(token).ConfigureAwait(false); } responseTimeDuration.ComputeServerTotal(); foreach (var pendingLazyOperation in pendingLazyOperations) { Action <object> value; if (onEvaluateLazy.TryGetValue(pendingLazyOperation, out value)) { value(pendingLazyOperation.Result); } } responseTimeDuration.TotalClientDuration = sw.Elapsed; return(responseTimeDuration); } finally { pendingLazyOperations.Clear(); } }