private async Task PerformScanAsync(ScanRequest request, SiteConfiguration siteConfiguration) { var token = await _apiTokenProvider.GetTokenAsync(AuthenticationOptions.Create(siteConfiguration)); using (var client = _httpClientFactory.CreateClient()) { client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); client.BaseAddress = new Uri(siteConfiguration.Url); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); _logger.LogInformation("Initializing scanning pipeline"); InputQueue = new BufferBlock <ScanItemTask>(); ScanBlock = new TransformManyBlock <ScanItemTask, StoreItemTask>(async(scanTask) => await ScanItemRecursive(client, siteConfiguration.SiteId, scanTask), new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = siteConfiguration.MaxThreads, SingleProducerConstrained = true } ); StoreBlock = new ActionBlock <StoreItemTask>(StoreItemAsync, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = siteConfiguration.MaxThreads, SingleProducerConstrained = true }); InputQueue.LinkTo(ScanBlock, new DataflowLinkOptions { PropagateCompletion = true }); ScanBlock.LinkTo(StoreBlock, new DataflowLinkOptions { PropagateCompletion = true }); _logger.LogInformation("Sending initial scan task"); await InputQueue.SendAsync(new ScanItemTask { Url = "API/api/systembrowser", ScanRequest = request }); await StoreBlock.Completion; } }