public SearchResult GetResults(SearchRequest searchRequest) { if (string.IsNullOrEmpty(searchRequest.Query)) { return(new SearchResult()); } if (searchRequest.SystemIds == null || searchRequest.SystemIds.Count() == 0) { return(new SearchResult()); } var cachedResults = _searchResultPositionRepository.Get( x => searchRequest.SystemIds.Contains(x.SearchConnectorId) && (x.Query == searchRequest.Query.ToLower() || x.Description.ToLower().Contains(searchRequest.Query.ToLower())) ).OrderByDescending(x => x.Date); if (cachedResults.Count() > 0) { var connectorId = cachedResults.First().SearchConnectorId; var positions = cachedResults.Where(x => x.SearchConnectorId == connectorId).Take(10); SearchResult searchResult = new SearchResult(); searchResult.SearchPositions = positions.ToList(); searchResult.SearchSystem = connectorId; return(searchResult); } var connectors = _searchConnectorRepository.Get(x => searchRequest.SystemIds.Contains(x.Id)).ToList(); int connectorsCount = connectors.Count; SearchResult[] results = new SearchResult[connectorsCount]; SearchResult finalResult = new SearchResult(); finalResult.SearchSystem = 1; List <Task> tasks = new List <Task>(); for (int i = 0; i < connectorsCount; i++) { results[i] = new SearchResult(); int currentIndex = i; var searchTask = Task.Run(() => GetResultPosition(connectors[currentIndex], searchRequest.Query, out results[currentIndex])); tasks.Add(searchTask); } while (tasks.Count() > 0) { Task.WaitAny(tasks.ToArray(), 3000); if (results.Where(x => x.SearchPositions.Count > 0).Count() > 0) { finalResult = results.Where(x => x.SearchPositions.Count > 0).First(); break; } List <int> removeTasks = new List <int>(); for (int i = 0; i < tasks.Count; i++) { if (tasks[i].Status != TaskStatus.Running) { removeTasks.Add(i); } } //Ни один таск не завершился => таймаут if (removeTasks.Count == 0) { break; } removeTasks.Reverse(); //Если удалять таски то с конца, чтобы не нарушить очередность foreach (int number in removeTasks) { tasks.Remove(tasks.ElementAt(number)); } } if (finalResult.SearchPositions.Count > 0) { finalResult.SearchPositions = finalResult.SearchPositions.Take(10).ToList(); foreach (var searchPosition in finalResult.SearchPositions) { searchPosition.Query = searchRequest.Query.ToLower(); searchPosition.SearchConnectorId = finalResult.SearchSystem; searchPosition.Date = DateTime.UtcNow; _searchResultPositionRepository.Insert(searchPosition); } } return(finalResult); }