В чем разница между задачей и потоком?
В С# 4.0 мы имеем Task
в пространстве имен System.Threading.Tasks. Какова истинная разница между Thread
и Task
. Я сделал некоторую пробную программу (помощь, взятую из MSDN) ради моего собственного обучения с помощью
Parallel.Invoke
Parallel.For
Parallel.ForEach
но есть много сомнений, поскольку идея не так ясна.
Сначала я искал в Stackoverflow для подобного типа вопроса, но, возможно, с этим вопросом заголовка я не смог получить то же самое. Если кто-то знает о том же типе вопроса, который был отправлен здесь ранее, любезно дайте ссылку на ссылку.
Ответы
Ответ 1
Задача - это то, что вы хотите сделать.
Нить является одним из многих возможных работников, выполняющих эту задачу.
В терминах .NET 4.0 Task представляет собой асинхронную операцию. Thread (s) используются для завершения этой операции, разбивая работу на куски и назначая отдельные потоки.
Ответ 2
В терминах компьютерной науки a Task
- это будущее или обещание. (Некоторые люди используют эти два термина синонимично, некоторые используют их по-другому, никто не может договориться о точном определении.) В принципе, Task<T>
"promises", чтобы вернуть вам T
, но не сейчас, мед, m kinda busy, почему бы вам не вернуться позже?
A Thread
- это способ выполнения этого обещания. Но не каждому Task
нужен совершенно новый Thread
. (На самом деле создание потока часто нежелательно, потому что это намного дороже, чем повторное использование существующего потока из threadpool. Еще об этом в одно мгновение.) Если ожидаемое значение происходит из файловой системы или базы данных или сети, тогда нет необходимости в том, чтобы поток мог сидеть и ждать данных, когда он может обслуживать другие запросы. Вместо этого Task
может зарегистрировать обратный вызов для получения значений (значений), когда они будут готовы.
В частности, Task
не говорит, почему это так долго, чтобы вернуть значение. Возможно, потребуется много времени, чтобы вычислить, или может потребоваться много времени для извлечения. Только в первом случае вы использовали бы Thread
для запуска Task
. (В .NET потоки загружаются дорого, поэтому вы, как правило, стараетесь избегать их как можно больше и действительно используете их только в том случае, если хотите выполнить несколько сложных вычислений на нескольких процессорах. Например, в Windows поток имеет значение 12 & thinsp; KiByte (Я думаю), в Linux поток весит всего лишь 4 & thinsp; KiByte, в Erlang/BEAM даже 400 и thinsp; Byte. В .NET это 1 и thinsp; MiByte!)
Ответ 3
Когда мы выполняем действия на нескольких потоках, он не гарантирует, что потоки разделены между несколькими процессорами.
Задача - это легкий объект для управления параллелизуемой единицей работы. Его можно использовать, когда вы хотите что-то выполнить параллельно. Параллельно означает, что работа распределена между несколькими процессорами, чтобы максимизировать вычислительную скорость. Задачи настраиваются для использования многоядерных процессоров.
Задача содержит следующие мощные функции по потоку.
- Если система имеет несколько задач, то она использует пул потоков CLR
внутренне, и поэтому не имеют накладных расходов, связанных с созданием
выделенный поток с использованием Thread. Также уменьшите контекст
время переключения между несколькими потоками.
- Задача может возвращать результат. Прямого механизма для возврата результата из потока нет.
-
Подождите набор задач без создания сигнализации.
-
Мы можем объединить задачи вместе для выполнения друг за другом.
-
Установите отношения родительский/дочерний, когда одна задача запускается из
другая задача.
-
Исключение дочерней задачи может распространяться на родительскую задачу.
-
Отмена поддержки задачи с помощью токенов отмены.
-
Асинхронная реализация в задаче проста, используя async и
'Ждут ключевые слова.
Ответ 4
Нить
Простая вещь, вам, вероятно, не нужно ее использовать, вы, вероятно, можете использовать задачу LongRunning
и воспользоваться преимуществами TPL - Task Parallel Library, включенной в .NET Framework 4 (февраль 2002 г.) и выше (также).NET Core).
Задачи
Абстракция над потоками. Он использует пул потоков (если вы не LongRunning
задачу как операцию LongRunning
, если так, то новый поток будет создан для вас под капотом).
Пул потоков
Как следует из названия: пул потоков. .NET Framework обрабатывает ограниченное количество потоков для вас. Зачем? Потому что открытие 100 потоков для выполнения дорогостоящих операций с процессором на процессоре с 8 ядрами определенно не очень хорошая идея. Фреймворк будет поддерживать этот пул для вас, повторно используя потоки (не создавая/не убивая их при каждой операции), и выполняя некоторые из них параллельно, таким образом, чтобы ваш ЦП не работал.
Хорошо, но когда использовать каждый?
В резюме: всегда используйте задачи.
Задача - это абстракция, поэтому ее намного проще использовать. Я советую вам всегда пытаться использовать задачи, и если вы сталкиваетесь с какой-то проблемой, которая заставляет вас обрабатывать поток самостоятельно (вероятно, в 1% случаев), то используйте потоки.
НО знать, что:
- Привязка ввода/вывода: для операций, связанных с
LongRunning
/выводом (вызовы базы данных, чтение/запись файлов, вызовы API и т.д.), LongRunning
использования обычных задач, используйте задачи LongRunning
(или потоки, если вам нужно). Потому что использование задач приведет вас к пулу потоков с несколькими занятыми потоками и множеством других задач, ожидающих своей очереди, чтобы занять пул. - CPU Bound: Для операций с CPU просто используйте обычные задачи (которые внутренне будут использовать пул потоков) и будьте счастливы.
Ответ 5
Следующие два видео с канала-9 помогут вам лучше понять задачи и темы и где их использовать.
http://channel9.msdn.com/blogs/bruceky/how-to-parallelize-your-application-part-2-theads-v-tasks
http://channel9.msdn.com/blogs/bruceky/how-to-parallelize-your-application-part-3-using-tasks
И если у вас есть еще немного времени, начните с этого видео
http://channel9.msdn.com/blogs/bruceky/how-to-parallelize-your-application-part-1-why-do-it
Ответ 6
Вы можете использовать Task
, чтобы указать, что вы хотите сделать, а затем прикрепите Task
с помощью Thread
. так что Task
будет выполняться в этом недавно созданном Thread
, а не в потоке GUI.
Используйте Task
с помощью TaskFactory.StartNew(Action action)
. Здесь вы выполняете делегат, поэтому, если вы не использовали ни одного потока, он будет выполнен в том же потоке (поток графического интерфейса). Если вы отметили поток, вы можете выполнить этот Task
в другом потоке. Это ненужная работа, потому что вы можете напрямую выполнить делегирование или присоединить этот делегат к потоку и выполнить делегирование в этом потоке. Так что не используйте его. это просто лишний. Если вы намерены оптимизировать свое программное обеспечение, это хороший кандидат для удаления.
** Обратите внимание, что Action
является delegate
.
Ответ 7
В дополнение к вышеприведенным пунктам было бы полезно знать, что:
- Задачей по умолчанию является фоновая задача. У вас не может быть задачи переднего плана. С другой стороны, поток может быть фоновым или передним (используйте свойство IsBackground для изменения поведения).
- Задачи, созданные в пуле потоков, перерабатывают потоки, которые помогают экономить ресурсы. Поэтому в большинстве случаев задачи должны быть вашим выбором по умолчанию.
- Если операции выполняются быстро, гораздо лучше использовать задачу вместо потока. Для длительных операций задачи не дают больших преимуществ перед потоками.
Ответ 8
Обычно я использую Task
для взаимодействия с Winforms и простым фоновым рабочим, чтобы он не зависал. вот пример, когда я предпочитаю использовать Task
private async void buttonDownload_Click(object sender, EventArgs e)
{
buttonDownload.Enabled = false;
await Task.Run(() => {
using (var client = new WebClient())
{
client.DownloadFile("http://example.com/file.mpeg", "file.mpeg");
}
})
buttonDownload.Enabled = true;
}
В.С.
private void buttonDownload_Click(object sender, EventArgs e)
{
buttonDownload.Enabled = false;
Thread t = new Thread(() =>
{
using (var client = new WebClient())
{
client.DownloadFile("http://example.com/file.mpeg", "file.mpeg");
}
this.Invoke((MethodInvoker)delegate()
{
buttonDownload.Enabled = true;
});
});
t.IsBackground = true;
t.Start();
}
разница в том, что вам не нужно использовать MethodInvoker
и более короткий код.
Ответ 9
Задача похожа на операцию, которую вы хотите выполнить, Thread помогает управлять этой операцией через несколько узлов процесса. задача - это легкий вариант, так как многопоточность может привести к сложному управлению кодом
Я буду предлагать читать из MSDN (Лучший в мире) всегда
задача
Нить
Ответ 10
Вот хороший блог, объясняющий разницу https://peterdaugaardrasmussen.com/2018/11/08/csharp-what-is-the-difference-between-threads-and-tasks/