我创建了一个小例子,也许您可以在那里找到最适合您的情况的最佳方法。
dotnet fiddle 示例
有 3 个选项:
按顺序
正如标题所说,每个项目都是按顺序处理的。非常节省的方法,但不是处理 9000 个项目的最快方法:)
var list = GenerateItems();
var count = list.Count();
for(var i = 0; i < count; i++)
{
InsertInDatabaseAsync($"{i}", list.ElementAt(i)).GetAwaiter().GetResult();
}
使用 Parallel.For 库
就像评论中所说的那样,它对 CPU 绑定处理很有好处,但在异步方法上有一些不足(这里)
var list = GenerateItems();
var count = list.Count();
var options = new ParallelOptions{MaxDegreeOfParallelism = MAX_DEGREE_OF_PARALLELISM};
Parallel.For(0, count, options, (i) =>
{
InsertInDatabaseAsync($"{i}", list.ElementAt(i)).GetAwaiter().GetResult();
});
使用异步等待
我认为在您的示例中,这最适合您。每个项目都是并行处理的,直接开始处理并启动一个Task
. (从这里复制了异步扩展)
var list = GenerateItems();
var count = list.Count();
// Extensions method see in referenced SO answer
ForEachAsync(count, list, async (item, index) =>
{
await InsertInDatabaseAsync($"{index}", item);
}).GetAwaiter().GetResult();
...更新
感谢您的评论。我已将 async-await 实现更新为更简单的实现:
private static async Task ForEachAsync<T>(IEnumerable<T> enumerable, Func<T, int, Task> asyncFunc)
{
var itemsCount = enumerable.Count();
var tasks = new Task[itemsCount];
int i = 0;
foreach (var t in enumerable)
{
tasks[i] = asyncFunc(t, i);
i++;
}
await Task.WhenAll(tasks);
}
并且还将MAX_DEGREE_OF_PARALLELISM
集合添加到 1。这对推荐中描述的并行处理产生了巨大影响。
