Асинхронные делегаты против Thread / ThreadPool? - PullRequest
33 голосов
/ 03 декабря 2009

Мне нужно выполнить 3 параллельные задачи, и после завершения каждой задачи они должны вызывать одну и ту же функцию, которая выводит результаты.

Я не понимаю в .net, почему у нас есть Асинхронный вызов (делегат.

Я немного запутался, какой использовать когда? Теперь, в этом конкретном случае, что я должен использовать асинхронный вызов или класс Thread?

Я использую C #.

Ответы [ 8 ]

44 голосов
/ 05 января 2010

1. Асинхронные делегаты

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

BackgroundWorker против фона Тема

2. BackgroundWorker

  • Используйте BackgroundWorker , если у вас есть одна задача, которая выполняется в фон и необходимо взаимодействовать с пользовательский интерфейс. и используйте его, если вам все равно, когда они завершают свою задачу. Задача сортировки данных и вызовы методов в потоке пользовательского интерфейса обрабатывается автоматически через его основанная на событиях модель.
  • Избегайте BackgroundWorker , если (1) ваша сборка еще не ссылка на System.Windows.Form сборка, (2) вам нужна нить быть на переднем плане или (3) вы нужно манипулировать потоком приоритет.

3. ThreadPool

  • Используйте поток ThreadPool , когда требуется эффективность. ThreadPool помогает избежать накладных расходов, связанных с созданием, запуском и остановкой потоки.
  • Избегайте использования ThreadPool , если (1) задание выполняется в течение всего времени жизни вашего приложение, (2) вам нужна нить быть на переднем плане, (3) вы нужно манипулировать потоком приоритет или (4) вам нужна нить иметь фиксированную личность (прерывание, приостановка, обнаружение).

4. Класс резьбы

  • Используйте класс Thread для длительных задач и когда вы требовать функции, предлагаемые формальным модель потоков, например, выбор между передним планом и фоном темы, настройка приоритета потока, мелкозернистый контроль над нитью исполнение и т. д.
12 голосов
/ 03 декабря 2009

Я не понимаю в .net, почему у нас есть асинхронный вызов (Delegate.BeginInvoke () и Delegate.EndInvoke ()), а также класс Thread?

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

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

  • Потоки предназначены для выполнения вещей, которые никогда не заканчиваются.

Примеры:

Если вы читаете большой файл с диска и не хотите блокировать поток GUI, используйте асинхронный вызов.

Если вы лениво пишете один или несколько файлов в фоновом режиме, используйте пул потоков.

Если вы каждые несколько секунд опрашиваете файловую систему в поисках изменений, используйте поток.

5 голосов
/ 03 декабря 2009

Асинхронный метод по существу абстрагирует способ, которым фактически обрабатывается работа. Это может быть порождено в новом процессе, это может быть выполнено в отдельном потоке ... Это не имеет значения.

Все, что имеет значение, вы говорите:

  1. Запустите этот код при запуске.
  2. И запустите этот код, когда закончите.

Если будет предоставлен выбор, я буду использовать асинхронный метод API вместо реализации собственного механизма потоков каждый раз. Разработчики фреймворка сделали за вас тяжелую работу, зачем изобретать велосипед.

3 голосов
/ 26 марта 2010

Я не понимаю в .net, почему мы имеем Асинхронный вызов (Delegate.BeginInvoke () & Delegate.EndInvoke ()), а также Класс темы?

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

Thread класс использует Win32 BeginThread, так что вам не нужно. Пул потоков использует класс Thread, поэтому вам не нужно. BeginInvoke использует пул потоков, так что вам не нужно, и так далее.

1 голос
/ 21 марта 2013

Это давно забытый поток, но кое-что, о чем здесь вообще не упоминалось, было то, что существует два типа работы: вычисление и привязка ввода / вывода.

В случае работы, связанной с вычислением, это выполняется в отдельном потоке (если вы используете шаблон BackgroundWorker или Begin/End, это происходит из пула потоков; или, если вы решили создать свой собственный поток нить).

Связанные с другой стороны операции ввода-вывода выполняются в портах ввода-вывода (аппаратная поддержка) и не требуют потока; Доступ к файлу и сетевые сокеты - два примера задач, связанных с вводом / выводом.

1 голос
/ 03 декабря 2009

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

Кроме того, выполнение метода в созданном вручную потоке дает вам больше контроля, например, возможность прерывать поток, прерывать его, проверять его состояние, устанавливать его приоритет и т. Д.

Асинхронные делегаты используются, если вы хотите быстро заставить метод выполняться асинхронно.

Кроме того, EndInvoke позволяет вам возвращать объект, который позволяет вам получить результаты выполнения. Thread.Join, хотя и функционально эквивалентен, не позволяет вам ничего возвращать.

0 голосов
/ 03 декабря 2009

Delegate.BeginInvoke захватывает поток пула потоков и выполняет переданный делегат в этом потоке. Поэтому, когда вы используете BeginInvoke, .NET Framework выполняет много работы, например, создает новый поток, запускает его и т. Д.

Вы также можете взглянуть на ThreadPool.QueueUserWorkItem (делегат {/ * делать вещи * /}); для альтернативного подхода к асинхронным вызовам.

0 голосов
/ 03 декабря 2009

Если у вас длительный процесс (например, приложение формы, IIS, веб-служба, служба Windows), вам, вероятно, будет лучше использовать асинхронные методы. Потоки требуют системных ресурсов и накладных расходов. Я всегда стараюсь не создавать темы. Если я не могу, я пытаюсь полагаться на ThreadPool для их обработки / управления.

Вы можете получить более подробную информацию, если вы можете сообщить нам, какова ваша заявка.

BeginInvoke использует делегата за кулисами, а методы Async обычно этого не делают.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...