Когда использовать Multithread?

Когда вы используете потоки в приложении? Например, в простых операциях CRUD, использование smtp, вызов веб-сервисов, которые могут занять несколько времени, если сервер сталкивается с проблемами с полосой пропускания и т.д.

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

Это может быть вопрос "noob", но будет здорово, если вы поделитесь со мной своим опытом в потоках.

Спасибо

Ответ 1

Я добавил теги С# и .NET на ваш вопрос, потому что вы упоминаете С# в своем названии. Если это неточно, не стесняйтесь удалять теги.

Существуют разные стили многопоточности. Например, существуют асинхронные операции с функциями обратного вызова..NET 4 представляет параллельную библиотеку Linq. Стиль многопоточности, который вы использовали бы, или использовать его вообще, зависит от того, что вы пытаетесь выполнить.

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

Более традиционная многопоточность использует потоки в библиотеке .NET(в данном случае), как это предусмотрено System.Thread. Помните, что в начальных процессах на потоках есть некоторые накладные расходы, поэтому используйте только потоки, когда преимущества этого превышают эти накладные расходы. Вообще говоря, вы хотели бы использовать этот тип однопроцессорной многопоточности, когда задача, работающая под потоком, будет иметь длинные промежутки, в которых процессор может делать что-то еще. Например, ввод-вывод с жесткого диска (и, следовательно, из системы баз данных, использующей один) на много порядков медленнее, чем доступ к памяти. В качестве другого примера может быть и сетевой доступ. Многопоточность может позволить другому процессу работать, ожидая завершения этих медленных (по сравнению с процессором) операций.

Другим примером, когда я использовал традиционную многопоточность, является кэширование некоторых значений при первом доступе к определенной странице ASP.NET в сеансе. Я запускаю поток, так что пользователю не нужно ждать завершения кэширования, прежде чем взаимодействовать со страницей. Я также регулирую поведение, когда кеширование не выполняется до того, как пользователь запросит другую страницу, чтобы, если кеширование не завершено, это не проблема. Это просто ускоряет выполнение некоторых дополнительных запросов, которые ранее были слишком медленными.

Учитывайте также, что многопоточность требует обслуживания вашего приложения. Например, приложения с резьбой могут быть сложнее отлаживать.

Надеюсь, это немного ответит на ваш вопрос.

Ответ 2

Вы можете использовать потоки, если вам нужны разные пути выполнения. Это приводит (когда сделано правильно) к более гибким и/или более быстрым приложениям, но также приводит к более сложному коду и отладке.

В простом сценарии CRUD, возможно, это не так полезно, но, возможно, ваш пользовательский интерфейс потребляет медленный веб-сервис. Если ваш код привязан к вашему потоку пользовательского интерфейса, у вас будет невосприимчивый пользовательский интерфейс между вызовами службы.

В этом случае использование System.Threading.Threads может быть излишним, потому что вам не нужен такой контроль. Использование BackgrounWorker может быть лучшим выбором.

Threading - это что-то трудное для освоения, но преимущества при правильном использовании огромны, производительность является наиболее распространенной.

Ответ 3

Джозеф Альбахари очень хорошо его подвел здесь:

  • Поддержание адаптивного пользовательского интерфейса
  • Эффективное использование заблокированного CPU в противном случае
  • Параллельное программирование
  • Спекулятивное выполнение
  • Разрешающая обработка запросов одновременно

Ответ 4

Одной из причин использования потоков является разделение больших задач, связанных с ЦП, на несколько процессоров/ядер, чтобы закончить быстрее. Другой - позволить расширенной задаче выполнять асинхронно, поэтому передняя часть может оставаться отзывчивой во время ее выполнения.

Ваши примеры, похоже, концентрируются на втором из них. Хотя это может быть хорошей причиной, если вы можете вместо этого использовать асинхронный ввод-вывод, что обычно предпочтительнее (например, почти все, что использует сокеты, может/будет лучше использовать сокеты (а) асинхронно). Асинхронный ввод-вывод легче отменить, и, как правило, он также имеет более низкую нагрузку на ЦП.

Ответ 5

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

Используя потоки, вы можете лучше использовать мощь многоядерных/процессорных машин.

Мониторинг некоторых данных в фоновом режиме вашего приложения.

Есть десятки таких сценариев.

Ответ 6

Понимание моего комментария может быть достаточным в качестве ответа...

Мне нравится просматривать многопоточные сценарии с точки зрения ресурсов. Другими словами, пользовательский интерфейс (графический интерфейс), сетевое взаимодействие, диск IO, процессор (ядра), оперативная память и т.д. Я считаю, что это помогает при решении вопроса о том, где использовать многопоточность в общем смысле.

Поводом для этого является просто то, что я могу использовать один ресурс в определенном потоке (например, Disk IO), в то же время используя другой поток, чтобы выполнить что-то другое с использованием другого ресурса.