public void GetItems_Cancelation_CancelAllRequestAfterError() { var item = new Item(); service = new ParallelQueueKeywordsSearchService(stackExchange, config2); A.CallTo(() => stackExchange.GetItemsAsync(A <Keyword> .Ignored, A <CancellationToken> .Ignored)) .Throws <Exception>(); var words = new[] { "1", "2", "3", "4", "5" }; Assert.Throws <KeywordsSearchExecutionException>(() => { var res = service.GetItems(words); }); A.CallTo(() => stackExchange.GetItemsAsync(A <Keyword> .Ignored, A <CancellationToken> .Ignored)) .MustHaveHappenedTwiceOrLess(); }
public IReadOnlyList <Item> GetItems(IEnumerable <string> words) { var keywords = GetKeywords(words); var keywordsQueue = new ConcurrentQueue <Keyword>(keywords); int httpWorkersCount = Math.Min(config.StackExchangeQueueMaxSize, keywords.Length); var tasks = new Task <List <Item> > [httpWorkersCount]; var cts = new CancellationTokenSource(); for (int i = 0; i < httpWorkersCount; i++) { tasks[i] = Task.Run(async() => { var res = new List <Item>(); while (!keywordsQueue.IsEmpty) { cts.Token.ThrowIfCancellationRequested(); if (keywordsQueue.TryDequeue(out var keyword)) { var items = await stackExchange.GetItemsAsync(keyword, cts.Token); res.AddRange(items); } } return(res); }); } try { Task.WaitAll(tasks); } catch (AggregateException e) { throw new KeywordsSearchExecutionException("Error ", e); } var res = ArgegateTasksResult(tasks); return(res.OrderBy(x => x.CreationDate).ToArray()); }