如何在异步任务C#中每秒限制请求

时间:2019-05-15 14:00:13

标签: c# asynchronous task azure-cosmosdb

我正在编写一个与Azure Cosmos DB交互的应用程序。我需要在Session中将30,000条记录提交给CosmosDB。因为我使用.NET Core,所以无法使用BulkInsert dll。因此,我使用Foreach循环插入CosmosDB。但是我看到每秒请求太多,并且CosmosDB超出了RU限制。

foreach(item in listNeedInsert){
      await RequestInsertToCosmosDB(item);
}

当请求数达到100时,我想暂停foreach循环。完成100次请求后。 foreach将继续。

3 个答案:

答案 0 :(得分:2)

您可以对列表进行分区并等待结果:

var tasks = new List<Task>();

foreach(item in listNeedInsert)
{
    var task = RequestInsertToCosmosDB(item);
    tasks.Add(task);

    if(tasks.Count == 100)
    {
        await Task.WhenAll(tasks);
        tasks.Clear();
    }
}

// Wait for anything left to finish
await Task.WhenAll(tasks);

每当您有100个任务在运行时,代码将等待它们全部完成后再执行最后一批。

答案 1 :(得分:0)

您可以在每100次迭代中设置一个延迟时间

int i = 1;
foreach(item in listNeedInsert)
{
      await RequestInsertToCosmosDB(item);
      if (i % 100 == 0)
      {
          i = 0;
          await Task.Delay(100); // Miliseconds
      }
      i++;
}

答案 2 :(得分:0)

如果您真的想最大化效率并且不能进行批量更新,请在本文中研究使用SemaphorSlim:

Throttling asynchronous tasks

一次对具有100个并发请求的中型数据库进行锤击不是一个好主意,因为它没有能力处理这种吞吐量。您可以尝试使用不同的调节数字来查看最佳值,但我想这是个位数的范围。

如果您想快速又肮脏地做某事,则可以使用Sean的解决方案。但我将“任务计数”从5开始而不是100。