.net не запускает задачи, как я заказываю - какова логика запуска новых задач

Поработав какое-то время, заметил, что, даже если вы создадите 1000 задач, они не запустятся сразу. Таким образом, в основном, даже если я запускаю 1000 задач, 100 из них выполняются и 900 из них ожидают запуска.

Итак, мой вопрос: как они начинают? Как .net определяет, когда запускать задачу или запускать ее? Какой методологии я могу следовать, чтобы начать их немедленно? Я хочу, чтобы определенное количество задач/потоков выполнялось все время.

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

Вопрос может быть не очень ясен, поэтому, пожалуйста, попросите меня уточнить.

В основном я порождаю 1000 (сохраняя это число порожденным. Когда 1 задача завершила запуск другой задачи) задач, но только 125 из них Running и 875 из них WaitingToRun :)

вот как я запускаю задачу

        Task.Factory.StartNew(() =>
        {
            startCheckingProxies();
        });

С# WPF 4.5


person MonsterMMORPG    schedule 03.03.2013    source источник
comment
Как именно вы создаете эти задачи? Какой у вас код?   -  person Shadow Wizard Wearing Mask V2    schedule 03.03.2013
comment
Задачи задуманы как независимые блоки: TPL будет запускать их по своему усмотрению. Может быть более эффективно запускать их блоками по 100 штук, чем пытаться распараллелить их все.   -  person Joe    schedule 03.03.2013
comment
@ShadowWizard добавил блок кода, чтобы посмотреть, как я это делаю.   -  person MonsterMMORPG    schedule 03.03.2013
comment
@ Джо, да, я также заметил, что TPL делает это :), но я хочу переопределить это, если это возможно. Это возможно ?   -  person MonsterMMORPG    schedule 03.03.2013
comment
Это в основном противоречит тому, что пытается сделать TPL. Задачи довольно абстрактны; если вы пытаетесь форсировать распараллеливание, это скорее деталь реализации, которая выходит за рамки этой абстракции. Просто используйте потоки в этом случае, но помните о нагрузке на ресурсы, которая может возникнуть в вашей системе.   -  person Joe    schedule 03.03.2013
comment
Ответ: ThreadPool.SetMaxThreads(10000, 10000); ThreadPool.SetMinThreads(10000, 10000); и никто не дал этот простой ответ   -  person MonsterMMORPG    schedule 03.03.2013
comment
Если бы в вашей компании было четыре фургона и четыре водителя, и я дал бы вам тысячу посылок для доставки, стали бы вы доставлять их все одновременно? Конечно, нет. Вы доставите сразу столько, сколько сможете эффективно, и заставите остальных ждать. Как долго они ждут? Пока не будет водителя и фургона.   -  person Eric Lippert    schedule 03.03.2013
comment
Ваше решение возиться с пулом потоков ухудшит, а не улучшит ситуацию. Предположим, у вас есть четыре фургона и десять тысяч водителей, и снова нужно доставить тысячу посылок. Теперь вы передаете по одной посылке каждому из 1000 водителей, платите зарплату остальным 9000 бездействующим водителям, и тысяча водителей по очереди водят фургон на протяжении квартала. Весь смысл асинхронности на основе задач состоит в том, чтобы не допустить этого. Не злоупотребляйте системой.   -  person Eric Lippert    schedule 03.03.2013
comment
@EricLippert я пытался, и это определенно стало лучше :) теперь я могу собирать урожай быстрее. У меня тоже достаточно ресурсов, но .net этого не знает. У меня есть 850 МБ ввода-вывода в секунду для записи и чтения и 50-мегабитное оптоволоконное соединение. Во всяком случае, прямо сейчас svchost exe получает 1 ядро ​​​​100% :) Мне нужно найти, как я могу запустить svchost с несколькими ядрами или запустить несколько svchost network exe :)   -  person MonsterMMORPG    schedule 04.03.2013
comment
связаны ли ваши задачи с io или процессором?   -  person Eric Lippert    schedule 04.03.2013
comment
@EricLippert мои задачи привязаны к сети   -  person MonsterMMORPG    schedule 04.03.2013
comment
Ну тогда это ваша проблема. По умолчанию планировщик предполагает, что вы создаете задачи, привязанные к процессору. Вы вообще не должны создавать много тем; вы должны запланировать поток завершения ввода-вывода, чтобы вызвать ваш основной поток обратно, когда сетевое задание завершится. Вы можете сделать это с очень небольшим количеством потоков. Помните, что потоки стоят безумно дорого; относитесь к ним так же, как к найму нового сотрудника. Вы не нанимаете одного почтальона на каждый доставленный конверт.   -  person Eric Lippert    schedule 04.03.2013
comment
@EricLippert, лол, я не так уж и невежественен. если бы потоки были дорогими для процессора, я бы уже знал, что не должен создавать много потоков. вот почему я спрашивал. TPL недостаточно умен.   -  person MonsterMMORPG    schedule 05.03.2013
comment
Нет, дело не в том, что потоки требуют больших ресурсов ЦП; именно в тех случаях, когда потоки НЕ требуют больших затрат процессора, вам не нужно создавать их много! Последнее, что вам нужно сделать, это создать десять тысяч потоков, каждый из которых занимает 0,01% ЦП, потому что это десять гигабайт стека в файле подкачки. Если у вас много задач, не связанных с процессором, не давайте их большому количеству потоков. Предоставьте их одному потоку, который может обрабатывать выполнение всех задач.   -  person Eric Lippert    schedule 05.03.2013
comment
@EricLippert Lippert, как бы вы с помощью 1 потока собирали 100 URL-адресов из Интернета одновременно?   -  person MonsterMMORPG    schedule 07.03.2013
comment
@MonsterMMORPG: Напоминаю, что это сайт вопросов и ответов. Если это действительно ваш вопрос, задайте новый вопрос.   -  person Eric Lippert    schedule 07.03.2013
comment
Но в целом, я думаю, вы пытаетесь оптимизировать не то. У вас проблема с сетью, и вы пытаетесь увеличить загрузку процессора. Это прямо противоположно тому, что вы должны делать; если проблема связана с сетью, вам следует попытаться свести к минимуму использование вашего процессора и максимально использовать сетевую карту. Если ваша проблема на самом деле связана с процессором, позвольте библиотеке параллельных задач выполнить свою работу; это хорошо для планирования вашего процессора. Если ваша проблема не связана с процессором, то TPL не подходит; используйте асинхронный http-клиент.   -  person Eric Lippert    schedule 07.03.2013


Ответы (2)


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

Конечно, это просто описание высокого уровня, логика более сложная и реализует множество оптимизаций.

Дополнительную информацию можно найти здесь и здесь

Вы также можете запускать задачи с перегрузкой StartNew, что позволяет вам настраивать параметры и настройки планировщика< /а>. Обратите внимание, однако, что работа с большим количеством потоков, скорее всего, приведет к ухудшению производительности. Создание потоков и переключение контекста имеют значительные затраты, а запуск тысяч потоков, IMO, приведет к обратным результатам.

person Zdeslav Vojkovic    schedule 03.03.2013

Задачи на самом деле просто потоки под капотом.

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

Я почти уверен, что оптимальное число не будет тысячей; Я написал службы Windows, в которых оптимальное количество одновременно выполняемых потоков равно количеству ядер в машине (в моем случае было 4).

person Robert Harvey    schedule 03.03.2013
comment
большое спасибо за ответ. Могу ли я переопределить этот пул потоков? я хочу решить сам, а не netframework. - person MonsterMMORPG; 03.03.2013
comment
Вы думаете, что знаете лучше, чем пул потоков? :) Конечно, вы можете, просто раскручивайте свои собственные темы. - person Robert Harvey; 03.03.2013
comment
я не думаю, но я хочу попробовать :) - person MonsterMMORPG; 03.03.2013
comment
например, когда я впервые открыл эту тему, было 125, а сейчас работает 224 :) - person MonsterMMORPG; 03.03.2013
comment
Если вы действительно хотите запустить столько потоков, вам, вероятно, лучше запустить свою программу на своем графическом процессоре (вашей видеокарте). Если у вас есть NVIDIA, вы можете найти библиотеку CUDA; иначе вы можете проверить OpenGL. - person Pieter Geerkens; 03.03.2013
comment
Многие оптимизации и трюки (например, кража работы) выполняются за кулисами, так что это будет непросто. кроме того, вы можете указать уровень параллелизма и другие параметры на TaskScheduler: msdn.microsoft.com /en-us/library/dd321282.aspx - person Zdeslav Vojkovic; 03.03.2013
comment
в настоящее время использование процессора очень низкое. количество запущенных задач также увеличивается со временем. сейчас выполняется 301 задание. но я хочу, чтобы он установил сумму, которую я хочу :) разве это не возможно? также мой процессор 8 ядер @ 4,5 ГГц - person MonsterMMORPG; 03.03.2013
comment
количество запущенных потоков увеличилось до 415. оно увеличивается с течением времени. но я хочу начать с этого счета :) разве это не возможно? - person MonsterMMORPG; 03.03.2013
comment
Задачи — это не потоки. Задачи похожи на задания, а потоки — на рабочих; у вас может быть миллион задач и только один поток; задачи не влекут за собой автоматически несколько потоков. - person Eric Lippert; 03.03.2013
comment
@EricLippert да, я узнал об этом, но в моем сценарии почти каждая задача получает свой собственный поток. Проверяю через диспетчер задач. - person MonsterMMORPG; 04.03.2013
comment
@MonsterMMORPG: В вашем сценарии каждая задача получает свой собственный поток, потому что вы сообщаете параллельной библиотеке задач, что каждая задача связана с процессором. TPL пытается назначать потоки задачам, чтобы наиболее эффективно использовать процессоры, но если вы лжете ему о том, привязаны ли эти задачи к процессору, тогда он не будет хорошо выполнять свою работу и будет выделять слишком много. много потоков. Вы не используете правильный инструмент для работы здесь; используйте TPL, когда у вас есть куча задач с интенсивным использованием ЦП, которые необходимо запланировать на различные процессоры. - person Eric Lippert; 07.03.2013