Есть ли издержки нескольких Task.Run, которые ожидают, не возвращая? - PullRequest
1 голос
/ 23 апреля 2020

Из 1000 созданных задач, допустим, будет выполнено только несколько (10), в зависимости от того, что taskCompletionSource успешно выполняется в какой-то другой части кода. Это означает, что ProcessWorkItemAsync готово будет напечатано только 10 раз.

код:

for (var i = 0;i<1000; i++)
{
     Task.Run(() => {
      await ProcessWorkItemAsync(); 
      Console.WriteLine("ProcessWorkItemAsync finished");
     }); 

}

async Task<TaskCompletionSource<int>> ProcessWorkItemAsync()
{
    return new TaskCompletionSource<int>();
}
  1. Есть ли нагрузка ЦП на 990, задача не выполняется и быть в подвешенном состоянии?
    • Из того, что я прочитал, поток не будет заблокирован, он будет возвращен в пул потоков, поэтому с точки зрения ЦП нет никаких дополнительных затрат. Что-то еще мне не хватает?
  2. Есть ли накладные расходы памяти?
    • из-за сохранения стеков вызовов, поскольку точка net должна отслеживать, куда вернуться.
    • Я предполагаю, что эти стеки вызовов будут сохранены в куче и сохранят память стоимость?

Ответы [ 2 ]

4 голосов
/ 24 апреля 2020

Из 1000 созданных задач, скажем, только немногие (10) будут выполнены, основываясь на успешном выполнении taskCompletionSource в какой-то другой части кода. Это означает, что ProcessWorkItemAsyn c готово будет напечатано только 10 раз.

Код, который вы опубликовали, не имеет такого поведения. Размещенный код будет напечатан "ProcessWorkItemAsync finished" 1000 раз, и все задачи будут выполнены практически сразу. В остальной части этого ответа я собираюсь ответить на вопросы и проигнорировать код.

Есть ли нагрузка ЦП на задачу 990, которая не завершается и находится в подвешенном состоянии?

Нет.

Из того, что я прочитал, поток не будет заблокирован, он будет возвращен в пул потоков, поэтому с точки зрения ЦП не возникает никаких накладных расходов. .Что-то еще мне не хватает?

Задачи не являются потоками. Тот факт, что у вас есть 1000 задач, никоим образом не означает, что в них участвует или было задействовано 1000 потоков.

Task.Run выполняет работу очереди в пул потоков, но при использовании асинхронных задач с Task.Run этот пул потоков поток возвращается в пул потоков в любое время await должен асинхронно ждать. Завершены ли задачи или нет, несущественно.

Есть ли накладные расходы памяти?

Да. Задачи - это объекты, как и любой другой ссылочный тип. Они могут быть укоренены, как и любой другой ссылочный тип. И если они никогда не будут очищены (завершены), они могут быть утечка ресурсов , как и любой другой тип ссылки.

из-за сохранения стеков вызовов, так как точка net должен отслеживать, куда вернуться. Я предполагаю, что эти стеки вызовов будут храниться в куче и будут стоить памяти?

Вроде. Стеки вызовов не фиксируются и не сохраняются. Задача хранит только ее продолжения. Логично, что вы можете думать об этом как о «стеке вызовов», но он имеет глубину только 1. Таким образом, каждая задача будет поддерживать любой код, который await s это.

0 голосов
/ 24 апреля 2020

Задача - это обещание выполнить работу.

Не может быть задачи, которая просто будет в подвешенном состоянии бесконечно.

Вы можете иметь долгосрочные задачи, которые используют выделенный поток, но они не находятся в подвешенном состоянии, и если им когда-либо действительно нужно что-то await, выделенный поток, который был дан, удаляется, как работа будет возобновлена ​​в другом потоке, который будет потоком пула потоков, если вы не будете в значительной степени работать с планировщиками задач, используемыми для планирования работы, т.е. вы создали собственный планировщик для обработки этой возможности.

Если вы Вы запрашиваете количество задач, которые вы можете поставить в очередь, чтобы потоки работали, например, с помощью ConcurrentExclusiveTaskSchedulerPair, это может достигать десятков миллионов, если не больше, что я не уверен, от чего именно они зависят. Потребление памяти также кажется безумно низким, хотя, если вы попытаетесь использовать это количество, в какой-то момент вы начнете видеть безумные выделения 4-5 ГБ ОЗУ из ниоткуда. (Данные из моего собственного тестирования в те дни.)

...