0

我在 dotnet 核心中使用 httptrigger 函数,我在其中获取 Json 格式的 httprequest 数据。我需要在 Google Merchant Center 帐户中插入此值。几乎有 9000 行(每次都是动态数据)需要插入。我如何实现执行速度更快的 Parallel.for 逻辑。目前我正在为每个循环使用如下所示,但它需要更多时间。下面是代码。

string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic body = JsonConvert.DeserializeObject(requestBody);
for (int i =0;i<body.Count;i++)
{
  Product newProduct = InsertProduct(merchantId, websiteUrl,body[i]);
}
4

2 回答 2

1

我创建了一个小例子,也许您可​​以在那里找到最适合您的情况的最佳方法。

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。这对推荐中描述的并行处理产生了巨大影响。

在此处输入图像描述

于 2021-05-25T10:45:52.450 回答
0

做这个。

string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic body = JsonConvert.DeserializeObject(requestBody);
Parallel.For(0, body.Count, i => {
    Product newProduct = InsertProduct(merchantId, websiteUrl,body[i]);
});
于 2021-05-23T11:04:52.950 回答