Большинство программистов .NET начинают свое знакомство с асинхронностью и параллельностью с метода Thread.Start. Это полезно для понимания внутренних механизмов работы многопоточности, но очень вредно для написания production кода.

Вызов Thread.Start чаще всего используется в двух случаях: когда вам надо запустить длительные вычисления параллельно с основным потоком и когда необходимо выполнить некоторый вызов без блокировки основного потока. Эти задачи похожи между собой но эффективно реализуются различными способами.

Откладывание вызова

Для данной операции можно использовать

  1. Пул потоков: System.Threading.ThreadPool - не рекомендуется.
  2. SynchronizationContext и его метод Post
  3. TPL

Выполнение длительной операции

Тут немного другие варианты будут удобны:

  1. BackgroundWorker - практически идеальный вариант для GUI так как содержит события для отслеживания хода выполнения.
  2. TPL при использовании продолжений

Использование ThreadPool для длительных вычислений крайне не рекомендуется, потому что количество потоков в пуле ограничено и создаются они небыстро. Поэтому запуск длительных вычислений в ThreadPool может привести к ухудшению производительности.

Как можно понять инструменты вроде TPL позволяют работать на нужном уровне абстракции. TPL может использовать SynchronizationContext, ThreadPool или создавать новые потоки для планирования задач.

UPD. Почему же не следует использовать Thread.Start. Это слишком низкоуровневое средство, создание потоков дорогое, нужно писать код для отмены вычислений, писать код для проброса исключений вызывающему методу, нужно, кроме того большое количество потоков в системе снижает производительность.

Теги : .NET