private async Task<SearchResult<IPackageSearchMetadata>> WaitForCompletionOrBailOutAsync( string searchText, IDictionary<string, Task<SearchResult<IPackageSearchMetadata>>> searchTasks, TelemetryState telemetryState, CancellationToken cancellationToken) { if (searchTasks.Count == 0) { return SearchResult.Empty<IPackageSearchMetadata>(); } var aggregatedTask = Task.WhenAll(searchTasks.Values); RefreshToken refreshToken = null; if (aggregatedTask != await Task.WhenAny(aggregatedTask, Task.Delay(DefaultTimeout))) { refreshToken = new AggregatedRefreshToken { TelemetryState = telemetryState, SearchString = searchText, SearchTasks = searchTasks, RetryAfter = DefaultTimeout }; } var partitionedTasks = searchTasks .ToLookup(t => t.Value.Status == TaskStatus.RanToCompletion); var completedOnly = partitionedTasks[true]; SearchResult<IPackageSearchMetadata> aggregated; if (completedOnly.Any()) { var results = await Task.WhenAll(completedOnly.Select(kv => kv.Value)); aggregated = await AggregateSearchResultsAsync(searchText, results, telemetryState); } else { aggregated = SearchResult.Empty<IPackageSearchMetadata>(); } aggregated.OperationId = telemetryState?.OperationId; aggregated.RefreshToken = refreshToken; var notCompleted = partitionedTasks[false]; if (notCompleted.Any()) { var statuses = notCompleted.ToDictionary( kv => kv.Key, kv => GetLoadingStatus(kv.Value.Status)); foreach (var item in statuses) { aggregated.SourceSearchStatus.Add(item); } var exceptions = notCompleted .Where(kv => kv.Value.Exception != null) .ToDictionary( kv => kv.Key, kv => (Exception) kv.Value.Exception); foreach (var item in exceptions) { aggregated.SourceSearchException.Add(item); } } if (_telemetryService != null && aggregated.SourceSearchStatus != null && aggregated.SourceSearchStatus.Values != null && telemetryState != null) { var loadingStatus = aggregated.SourceSearchStatus.Values.Aggregate(); if (loadingStatus != LoadingStatus.Loading && telemetryState.ShouldEmit) { telemetryState.Duration.Stop(); _telemetryService.EmitTelemetryEvent(new SearchPageTelemetryEvent( telemetryState.OperationId, telemetryState.PageIndex, aggregated.Items?.Count ?? 0, telemetryState.Duration.Elapsed, loadingStatus)); } } return aggregated; }