В чем разница Thread и Task в C#?
Что проверяют
Отличаете ли вы поток как ресурс операционной системы от задачи как единицы работы. Дальше почти всегда идёт вопрос про async/await.
Как отвечать
Thread это поток операционной системы: собственный стек около мегабайта, дорогое создание, переключение контекста, ручное управление жизненным циклом. Task это описание единицы работы, которая обычно выполняется на потоке из пула, а иногда не занимает поток вовсе.
Ключевые различия:
- стоимость: тысячу задач создать нормально, тысячу потоков нет;
- результат и ошибки:
Task<T>возвращает значение, исключение сохраняется внутри задачи и всплывает приawait. У потока результата нет, а необработанное исключение валит процесс; - композиция:
Task.WhenAll,WhenAny, продолжения, отмена черезCancellationToken. У потока для этого нет ничего, кромеJoinи грубого прерывания; - асинхронность без потока: задача, ожидающая ввода-вывода, не держит поток вообще. Это и есть главный выигрыш
async/await:Task.Runберёт поток из пула для вычислений, аawaitсетевого вызова просто освобождает поток до прихода ответа.
Отсюда правило: в современном коде почти всегда Task. Собственный Thread оправдан для долгоживущей фоновой работы с особыми требованиями, например с высоким приоритетом, своим размером стека или однопоточной моделью.
Где спотыкаются
Пишут Task.Run вокруг асинхронного вызова к базе или сети. Поток занимается зря, выигрыша нет.
Блокируют результат через .Result или .Wait() и получают взаимную блокировку в контексте синхронизации.
Считают, что async создаёт поток. Он не создаёт ничего, он лишь разбивает метод на продолжения.