#c_sharp #многопоточность
Closed. This question needs to be more focused. It is not currently accepting answers. Want to improve this question? Update the question so it focuses on one problem only by editing this post. Closed 4 года назад. В C# есть немало средств для работы с потоками. Это и Thread и BackgroundWorker и ThreadPool и даже Task с async и await. В этом многообразии недолго потеряться. Подскажите пожалуйста что и когда из всего этого использовать а то у меня уже голова кругом от всего этого кружится. Плюс еще Parallel/TPL/ В общем я теряюсь в этом многообразии
Ответы
Ответ 1
Если Вы собираетесь изучать многозадачное программирование, и спрашиваете, в каком порядке следует осваивать всё это многообразие, то я рекомендую такой: Для начала посмотрите на потоки (Thread). Поток — достаточно низкоуровневое понятие, он позволяет запустить параллельные вычисления, но не позволяет простым образом получить результат этих вычислений. Преимуществом потоков по сравнению с классической параллельностью на уровне процессов являются пониженные накладные расходы (разные потоки могут работать с одним и тем же адресным пространством). Однако потоки всё ещё достаточно ресурсоёмки, поскольку требуют около 1мегабайта ОЗУ на каждый поток. На этапе изучения потоков попробуйте освоить синхронизацию потоков через примитивы синхронизации (Mutex, Semaphore и пр.) и методы WaitOne, WaitAll. Разберитесь, как можно усыплять потоки, как устанавливать им приоритет, чем отличаются фоновые и нефоновые потоки. Факультатив — изучение коллекций, пригодных для параллельного использования (System.Collections.Concurrent). Следующая абстракция — пул потоков (Thread pool). Идеален, когда у вас есть много небольших задач, которые можно запускать параллельно. Вычислительные задачи такого рода встречаются нечасто, а вот асинхронный ввод/вывод хорошо ложится на такой сценарий. Пул потоков реализован на уровне Windows, а .NET использует Windows API. Чтобы пул работал, в Windows пришлось ввести специальное "тревожное" состояние потока. Обычно, заснувший или приостановленный поток не может выполнять никакой работы, но если он заснул или ожидает события в тревожном (alertable) состоянии, Windows может разбудить его для выполнения насущность задачи. На этом этапе попробуйте изучить классы ThreadPool и IAsyncResult, а также разберитесь с контекстом синхронизации (SynchronizationContext). Удобным развитием пула потоков в .NET являются задачи (Task). Задачи реализованы в т.н. Task Parallel Library (TPL), и значительно упрощают работу с короткими вычислениями и асинхронным вводом-выводом. По сути это обёртка над IAsyncResult. Также можете поиграться с Parallel LINQ на этом этапе. Наконец, финальным аккордом идут ключевые слова async/await. Если к этому моменту вы плотно поработали с IAsyncResult/Task, то никаких проблем возникнуть не должно.Ответ 2
Thread для того, чтобы: не занимать навсегда поток пула, поставить повышенный или пониженный приоритет, задать потоку имя, чтобы было удобнее искать его в отладчике. Во всех остальных случаях другие механизмы будут попросту проще в использовании. BackgroundWorker нужен, чтобы выполнить однократную или повторяющуюся фоновую задачу по запросу пользователя. Главное достоинство - можно "бросить" на форму из тулбокса. ThreadPool - это простой способ быстро и однократно породить дочерний поток для выполнения короткой задачи без взаимодействия с пользователем. Сюда же относится BeginInvoke на делегате. Task - это прежде всего абстракция значения, которое будет доступно в будущем - а уже потом способ создания нового потока. Существуют способы создать Task, который не будет выполнять никакой работы и потому не создаст нового потока - помните об этом. Фактически, это одно из достоинств задач - то, что они создают новые потоки только при необходимости. Является заменой BackgroundWorker и устраняет лапшу из методов BeginXxx и коллбеков. Task применим для выполнения фоновой задачи, инициированной пользователем, с последующим уведомлением пользователя о результате, для "быстрого" распараллеливания кода, для выполнения сетевых запросов, в качестве примитива синхронизации.Ответ 3
Если под .NET 4.5 - то однозначно Task + async/await. Task - это очень удобная обертка над ThreadPool и Thread. По умолчанию используется ThreadPool, но TaskCreationOptions можно задать использование Thread. Пример: th[i] = Task.Factory.StartNew(() => { // какие то действия } , new CancellationToken() , TaskCreationOptions.LongRunning // Указываем использовать Thread , TaskScheduler.Default); BackgroundWorker - для извращенцев и новичков. Много кода, мало толку. Но знать вы это всеравно должны. Thread\ThreadPool - морально устарело. Используется в старых версиях .NET. Знать в любом случае должны.
Комментариев нет:
Отправить комментарий