Я использую цикл ForEachAsync, как описано в этом сообщении в блоге на ссылка .
В моем теле цикла выполняется комбинация операций ввода-вывода (асинхронное / ожидание) и операций с привязкой к процессору.В таком случае, какие все факторы необходимо учитывать для определения степени параллелизма?
public static Task ForEachAsync<T>(
this IEnumerable<T> source,
int degreeOfParallelism,
Func<T, Task> body)
{
if (degreeOfParallelism <= 0)
{
throw new ArgumentOutOfRangeException(nameof(degreeOfParallelism));
}
return Task.WhenAll(
from partition in Partitioner
.Create(source)
.GetPartitions(degreeOfParallelism)
select Task.Run(async () =>
{
using (partition)
{
while (partition.MoveNext())
{
await body(partition.Current);
}
}
}));
}
public async Task ProcessChangesAsync(
IChangeFeedObserverContext context,
IReadOnlyList<Document> docs,
CancellationToken cancellationToken)
{
// This function receives list of documents that need to be processed in parallel
await docs.ForEachAsync(8, async doc =>
{
await ProcessDocument(doc);
});
}
public async Task ProcessDocument(Document doc)
{
// We get other details for this entity from database.
var dbResult = await repository.GetDetailsFromDB(doc);
// Get some more data from external services
var moreDetails = await httpClient.GetMoreDataFromOtherServices(dbResult);
// The data fetched above consists of list of elements and we iterate over the list and run business logic.
// Use data mappers to convert the data back to entities. These are all CPU bound operations
// Then finally we persist details in DB
await repository.WriteToDB(...);
}