Должен ли я заметить разницу в использовании Task vs Threads в .Net 4.0? - PullRequest
18 голосов
/ 29 ноября 2011

Я обновил свой код, чтобы использовать задачи вместо потоков ....

Глядя на использование памяти и ЦП, я не замечаю каких-либо улучшений на многоядерном ПК. Ожидается ли это?

Мое приложение по сути запускает потоки / задачи в разных объектах при запуске ...

Все, что я делаю, это просто

Task a = new Task(...)
a.Start();

Ответы [ 5 ]

29 голосов
/ 29 ноября 2011

Существуют различные последствия использования задач вместо потоков, но производительность не является существенной (при условии, что вы не создавали огромное количество потоков.) Несколько ключевых отличий:

  1. TaskScheduler по умолчанию будет использовать пул потоков, поэтому некоторые задачи могут не запуститься, пока не будут выполнены другие ожидающие задачи.Если вы используете Thread напрямую, каждое использование запускает новый поток.
  2. Когда в задаче возникает исключение, оно включается в исключение AggregateException, которое вызывающий код может получить, ожидая завершения задачи или если вызарегистрировать продолжение задачи.Это связано с тем, что вы также можете делать такие вещи, как ожидание завершения нескольких задач, и в этом случае могут генерироваться и объединяться несколько исключений.
  3. Если вы не наблюдаете необработанное исключение, выданное задачей, оно будетну, может) в конечном итоге будет брошен финализатором задания , что особенно неприятно.Я всегда рекомендую перехватывать событие TaskScheduler.UnobservedTaskException, чтобы вы могли как минимум регистрировать эти сбои до того, как приложение взорвется.Это отличается от исключений потока, которые отображаются в событии AppDomain.UnhandledException.
8 голосов
/ 29 ноября 2011

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

Что хорошего в Task, так это новые возможности, которые вы можете с ними делать

  • Композиция с ContinueWith
  • Аннулирование
  • Иерархии
  • И т.д. ...
4 голосов
/ 29 ноября 2011

Одним из замечательных улучшений Takss vs. Threads является то, что вы можете легко создавать цепочки задач. Вы можете указать, когда задача должна запускаться после предыдущей («OnSuccess», «OnError», a.s.o.), и вы можете указать, должно ли происходить переключение контекста синхронизации. Это дает вам прекрасную возможность запустить долгосрочное задание в bakcground и после этого ссылочную задачу пользовательского интерфейса в потоке пользовательского интерфейса.

0 голосов
/ 29 ноября 2011

Вы увидите разницу, если ваш исходный или преобразованный код не полностью не задействует процессор. То есть если исходный код всегда ограничивал количество потоков до 2, на четырехъядерном компьютере он будет работать с нагрузкой около 50% с потоками, созданными вручную, и потенциально с нагрузкой 100% с задачами (если ваши задачи могут быть фактически параллелизированы). Таким образом, похоже, что либо ваш исходный код был разумным с точки зрения производительности, либо обе системы сталкиваются с проблемами, демонстрирующими похожую недостаточную загрузку ЦП.

0 голосов
/ 29 ноября 2011

Если вы используете .Net 4.0, вы можете использовать метод Parallel.Invoke, например,

Parallel.Invoke(()=> {
    // What ever code you add here will get threaded.
});

для получения дополнительной информации см. http://msdn.microsoft.com/en-us/library/dd992634.aspx

...