C # Threading в реальных приложениях - PullRequest
5 голосов
/ 05 августа 2010

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

Я работал над некоторыми широко используемыми и хорошо спроектированными приложениями .NET в C #, но не нашел никаких следов явного использования. Нет ли реальной необходимости из-за того, что этим управляет CLR, или есть какая-то конкретная причина?

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

Ответы [ 10 ]

5 голосов
/ 05 августа 2010

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

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

Класс BackgroundWorker очень полезен здесь.

4 голосов
/ 05 августа 2010

- это потоки, применяемые явным образом как часть проектирования или разработки в реальных приложениях.

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

Нет ли реальной необходимости из-за того, что этим управляет CLR, или есть какая-то конкретная причина?

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

3 голосов
/ 05 августа 2010

Это полностью зависит от приложения.

Для клиента приложения, которое когда-либо должно выполнять какую-либо значительную работу (или выполнять другие потенциально длительные задачи, такие как выполнение вызовов веб-службы).) Я ожидаю, что будут использоваться фоновые темы.Этого можно достичь с помощью BackgroundWorker, явного использования пула потоков, явного использования Parallel Extensions или явного создания новых потоков.

Веб-службы и веб-приложения с меньшей вероятностью создают свои собственные потоки, вмой опыт.Вы с большей вероятностью будете эффективно обрабатывать каждый запрос как отдельный поток (даже если ASP.NET перемещает его внутри) и выполнять все синхронно.Конечно, являются веб-приложениями, которые либо выполняются асинхронно, либо запускают потоки по другим причинам - но я бы сказал, что это происходит реже, чем в клиентских приложениях.

2 голосов
/ 05 августа 2010

Определенно +1 на параллельных расширениях к .NET.Microsoft проделала большую работу по улучшению ThreadPool.Раньше у вас была одна глобальная очередь, которая обрабатывает все задачи, даже если они были созданы из рабочего потока.Теперь у них есть глобальная очередь без блокировки и локальные очереди для каждого рабочего потока.Это очень приятное улучшение.

Я не такой большой поклонник таких вещей, как Parallel.For, Parallel.Foreach и Parallel.Invoke (регионов), так как я считаю, что они должны быть чисто языковыми расширениями, а небиблиотеки классов.Очевидно, я понимаю, почему у нас есть этот промежуточный шаг, но для C # неизбежно получить улучшения языка для параллелизма, и в равной степени неизбежно, что нам придется вернуться и изменить наш код, чтобы воспользоваться этим: -)

В целом, если вы хотите создавать параллельные приложения в .NET, вы должны сами исследовать преимущества параллельных расширений.Я также думаю, что, учитывая то, что это довольно зарождающееся усилие со стороны Microsoft, вы должны очень активно рассказывать о том, что работает для вас, а что нет, независимо от того, что вы считаете своим уровнем мастерства в параллельности.Microsoft определенно слушает, но я не думаю, что есть много людей, которые еще используют Parallel Extensions.Вчера я был в VSLive Redmond и смотрел сессию на эту тему, и на меня произвела впечатление команда, работающая над этим.

Раскрытие информации: раньше я был директором по маркетингу в Visual Studio и сейчас нахожусь в стартапе Corensic , где мы создаем инструменты для обнаружения ошибок в параллельных приложениях.

1 голос
/ 05 августа 2010

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

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

По моему опыту, наиболее распространенное место для реализации многопоточности - в Windows Services (фоновые приложения) и в приложениях, в которых использовались сценарии использования, в которых объем работы можно легко разделить на меньшие участки работы ( и передается в потоки для завершения асинхронно).

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

Как уже упоминалось другими, команда Parallel Extensions ( блог здесь ) проделала большую работу по обеспечению безопасности потоков и параллельного выполнения, и вы можете найти некоторые примеры / примеры на сайте MSDN Code .

1 голос
/ 05 августа 2010

Большинство реальных применений потоков, которые я видел, - это просто избегать блокировок - пользовательский интерфейс, сеть, вызовы базы данных и т. Д.

Вы можете использовать его как BeginXXX и EndXXX методпары, delegate.BeginInvoke вызовы, Control.Invoke вызовы.

Некоторые системы, которые я видел, где многопоточность была бы благом, фактически используют принцип изоляции для достижения нескольких «потоков», другими словами, разделяютработать в совершенно не связанных друг с другом кусках и обрабатывать их все независимо друг от друга - «многопоточность» (или многоядерное использование) автоматически достигается простым запуском всех процессов одновременно.

Я думаю, что это справедливо дляДопустим, вы обнаружите, что множество прикладных программ (представление данных) в основном не требуют массовой парализации, и при этом они не всегда могут быть спроектированы так, чтобы подходить для них.Все примеры, которые я видел, - это очень специфические проблемы.Это может объяснять, почему вы не видели каких-либо заметных реализаций этого.

0 голосов
/ 05 августа 2010

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

Случай 1 - для систем, которые должны достигать чрезвычайно высокого уровня эксплуатационной надежности, в архитектуре голосования могут использоваться три совершенно отдельные подсистемы, использующие три разных механизма - порождает 3 потока / прохождения для каждого из избирателейподождите, пока они завершат / умрут / будут убиты, и продолжайте, если все они скажут одно и то же - пример - сложные авионические системы

Случай 2 - для систем, которые должны иметь дело с высокой степенью эксплуатационной неопределенности - сделайтето же самое, но когда что-то / что-то возвращается к вам, убейте отставших и отправляйтесь с лучшим ответом, который вы получили - пример - сложные алгоритмы внутридневной торговли, пытающиеся разрушить бизнес, которыйmploy их: -)

0 голосов
/ 05 августа 2010

Как современные дневные программисты, мы любим абстракции, поэтому мы используем потоки, вызывая методы Async или BeginInvoke и используя такие вещи, как BackgroundWorker или PFX в .Net 4.

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

0 голосов
/ 05 августа 2010

Большинство ответов ссылаются на длительные задачи в приложении с графическим интерфейсом. Другой очень распространенный сценарий использования в моем опыте - очереди Производителя / Потребителя. У нас есть много служебных приложений, которые должны выполнять веб-запросы и т. Д. Часто с большим количеством конечных точек. Мы используем шаблон потоков производителя / потребителя (обычно путем интеграции пользовательского пула потоков) для обеспечения высокой степени распараллеливания этих задач.

На самом деле, в этот самый момент я проверяю приложение, которое загружает файл размером 200 МБ в 200 различных мест FTP. Мы используем SmartThreadPool и выполняем до 50 параллельных загрузок, что позволяет завершить весь пакет менее чем за час (в отличие от более чем 50 часов, если все загрузки происходили последовательно - поэтому при нашем использовании мы найти почти прямые линейные улучшения во времени).

0 голосов
/ 05 августа 2010

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

Это самые распространенные из тех, что я видел.

...