Как ограничить количество запросов в секунду в асинхронной задаче C # - PullRequest
1 голос
/ 15 мая 2019

Я пишу приложение, которое взаимодействует с БД Azure Cosmos. Мне нужно передать 30 000 записей в CosmosDB за сессию. Потому что я использовал .NET Core, поэтому я не могу использовать DLL BulkInsert. Итак, я использую цикл Foreach для вставки в CosmosDB. Но я вижу слишком много запросов в секунду и перегружаем лимит RU CosmosDB.

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

Я хочу приостановить цикл foreach, когда число запросов достигнет 100. После выполненных 100 запросов. foreach будет продолжаться.

Ответы [ 3 ]

2 голосов
/ 15 мая 2019

Вы можете разделить список и дождаться результатов:

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 задач, код будет ждать их завершения до выполнения последнего пакета.

0 голосов
/ 22 мая 2019

Если вы действительно хотите максимизировать эффективность и не можете выполнять массовые обновления, изучите использование SemaphorSlim в этом посте:

Регулирование асинхронных задач

Удар по средеразмер базы данных с 100 одновременными запросами не является хорошей идеей, потому что она не оборудована для обработки такой пропускной способности.Вы можете попробовать поиграть с другим дросселирующим числом и посмотреть, что оптимально, но я бы предположил, что он находится в диапазоне одной цифры.

Если вы хотите сделать что-то быстрое и грязное, вы, вероятно, можете использовать решение Шона.Но я бы установил количество заданий равным 5, а не 100.

0 голосов
/ 15 мая 2019

Вы можете установить задержку на каждую сотню итераций

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