I had some problems in my code causing too many open connections which causes them to close and get no http response. I have since refactored into something that looks like this:
List<<List<string>> batches = splitListOfUrlStringsIntoBatches(urls, 50); // where 50 is the batch size
I then do:
foreach (var batchList in listOfBatchLists)
{
var insertForBatch = RunBatch(batchList);
allInsertAmounts.Add(insertForBatch);
}
and run batch looks like:
private int RunBatch(IEnumerable<string> batch)
{
var allWriteNum = 0;
// this will run on one bound logical thread i think
Parallel.ForEach(batch, (batchItem) => {
var res = Client.GetAsync(batchItem.Item1).GetAwaiter().GetResult();
var responseBody = res.Content.ReadAsStringAsync().GetAwaiter().GetResult();
var strongType = JsonConvert.DeserializeObject<StrongType>(responseBody);
dbContext.add(strongType);
allWriteNum++
});
return allWriteNum;
}
The thing is if i increase the batch size to something stupid like 50,000 i dont get any closed connection errors and now I am not sure why..
Is it because the Parallel.foreach has optimisation to create the best amount of tasks and it can somehow work out that doing this will cause too many open connections? or too much cpu work?
You are accessing external resource (through http client) - IO operations, that is what async-await was designed for.
public async Task<StrongType> GetAsync(Item item)
{
var response = await Client.GetAsync(item);
var body = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<StrongType>(body);
}
public async Task Run(IEnumerable<Item> items)
{
var tasks = items.Select(item => GetAsync(item));
await Task.WhenAll(tasks);
var loadedStrongTypes = tasks.Select(task => task.Result);
dbContext.AddRange(loadedStrongTypes);
}
Because code works with external resource, parallel approach will waste resources by creating many threads which doing nothing - only waiting for a response.
With async-await you will be able to send all requests without waiting for responses.
And when all responses successfully arrived you can proceed with processing received data.