Проблема даже с попытками сделать это заключается в том, что это сложная проблема. Для начала, как вы вообще надежно наблюдаете за использованием процессора и диска? Редакция выборки ЦП даст плохое представление о том, что на самом деле происходит, а выборка диска еще сложнее. Во-вторых, какова гранулярность ваших задач и как часто вы можете быстро и реально изменить число запущенных. В-третьих, все быстро меняется со временем, поэтому вам нужно применить какую-то фильтрацию к своим наблюдениям. В-четвертых, идеальное количество потоков будет зависеть от процессора, на котором фактически выполняется код. В-пятых, если вы выделите слишком много потоков, вы будете перебивать их, а не выполнять полезную работу.
См. http://msdn.microsoft.com/en-us/magazine/ff960958.aspx для обсуждения того, как Пул потоков в .NET справляется со сложной задачей определения количества используемых потоков.
Вы также можете использовать рефлектор и взглянуть на код, который TPL использует для распределения потоков и во избежание ненужного переключения контекста - это сложно и даже не учитывает доступ к диску!
Вместо этого вы можете попробовать выполнить задачи в потоке с более низким приоритетом (создать собственный TaskScheduler
, который будет запускать потоки с приоритетом ниже нормального, на самом деле довольно просто). Это, по крайней мере, гарантирует, что вы сможете запустить 100% CPU без ущерба для остальной системы. Неразбериха с приоритетами потоков сама по себе чревата проблемами, но если это чисто фоновая задача, она может быть простой и может помочь.
Часто использование диска является реальной причиной, когда речь идет о других приложениях, страдающих от одного жадного приложения. Windows может легко распределять ЦП между приложениями, но когда речь идет об относительно медленном доступе к диску, это совсем другое дело. Вместо того, чтобы пытаться динамически регулировать количество выполняемых потоков, вам может потребоваться просто ограничить приложение, чтобы оно не получало слишком частый доступ к диску. Это то, что вы можете сделать без изменения количества активных потоков.
Вы также можете посмотреть на SetPriorityClass
как способ информирования ОС о том, что ваш процесс менее важен, чем другие приложения, работающие в системе, см. Как повысить приоритет ввода / вывода процесса? для дополнительной информации. Но это предполагает, что весь ваш процесс менее важен, а не только эта его часть.