Животное на обложке — мусанг, или малайская пальмовая куница, — пожалуй, отлично подходит для представления темы этой книги. Пока я не увидел обложку, я ничего не знал о нем и поэтому решил поискать информацию. Мусанги считаются вредителями, потому что засоряют своим пометом чердаки и шумят. Их анальные железы выделяют секрет с противным запахом. Мусанг относится к исчезающим видам из категории «Вызывающие наименьшее опасение», что по сути является политкорректным аналогом утверждения «Убивайте сколько угодно; никому не жалко». Мусанги поедают спелые плоды кофейного дерева (кофейные вишни), которые проходят через их желудочно-кишечный тракт. Копи-лувак, один из самых дорогих видов кофе в мире, делается из кофейных зерен, извлеченных из испражнений мусанга. По утверждениям Американской ассоциации спешиалти кофе, «он просто имеет неприятный вкус».
Все это делает мусанга идеальным символом для конкурентной и многопоточной разработки. Для непосвященного конкурентность и многопоточность нежелательны. Из-за них добропорядочный код начинает вести себя совершенно непостижимым образом. Состояния гонки и т.д. приводят к катастрофическим сбоям (которые, похоже, всегда происходят в продакшен или во время демонстрации). Некоторые разработчики заходят настолько далеко, что заявляют: «Потоки — зло», и полностью избегают конкурентности. Немногочисленная группа разработчиков вошла во вкус и использует конкурентность без опасений; но многие в прошлом уже обжигались на ней, и от прошлого опыта у них остались неприятные воспоминания.
Тем не менее для современных приложений конкурентность становится практически обязательным требованием. В наши дни пользователь хочет видеть интерфейс, быстро реагирующий на происходящее, а серверным приложениям приходится масштабироваться до беспрецедентных уровней. Конкурентность способствует решению проблем в обоих направлениях.
К счастью, существует множество современных библиотек, которые значительно упрощают конкурентность! Параллельная обработка и асинхронное программирование перестали быть уделом избранных. Эти библиотеки повышают уровень абстракции, вследствие чего разработка масштабируемых приложений с хорошей скоростью реакции становятся вполне реальным делом для любого разработчика. Если в прошлом, когда конкурентное программирование было исключительно сложным делом и вы на нем обожглись, рекомендую сделать новую попытку, вооружившись современным инструментарием. Мы, наверное, никогда не сможем назвать конкурентность простым делом, но сейчас она уже не так сложна, как раньше!
Эта книга написана для разработчиков, которые хотят освоить современные подходы к конкурентному программированию. Предполагается, что читатель уже обладает опытом программирования .NET, включая понимание обобщенных коллекций, перечисляемых объектов и LINQ. Знание многопоточного или асинхронного программирования не потребуется. Если у вас имеется некоторый опыт в этих областях, книга все равно может вам пригодиться, потому что в ней представлены новые библиотеки — более безопасные и простые в использовании.
Конкурентность полезна в приложениях любого типа. Неважно, работаете ли вы над настольными, мобильными или серверными приложениями; в наши дни конкурентность стала практически обязательным требованием во всех ситуациях. Рецепты, приведенные в книге, помогут вам сделать пользовательские интерфейсы более отзывчивыми, а серверы — лучше масштабируемыми. Мы уже достигли точки, в которой конкурентность получила повсеместное распространение, и понимание этих приемов и их применений стало одним из важнейших навыков профессионального разработчика.
На заре своей карьеры я изучал многопоточное программирование методом проб и ошибок. Затем я изучал асинхронное программирование методом проб и ошибок. Хотя и то и другое принесло полезный опыт, я бы предпочел иметь тогда некоторые инструменты и ресурсы, которые доступны сейчас. В частности, поддержка async и await в современных языках .NET — настоящее сокровище.
Однако если обратиться к сегодняшним книгам и другим ресурсам для изучения конкурентности, почти все они начинаются с изложения большинства низкоуровневых концепций. Обычно приводится превосходное описание потоков и примитивов синхронизации, а высокоуровневые методы откладываются на потом, если вообще рассматриваются. Полагаю, это происходит по двум причинам. Во-первых, многие разработчики конкурентных программ (включая меня) начинали с изучения низкоуровневых концепций и подолгу корпели над описаниями старых методов. Во-вторых, многие книги были написаны давно и содержат устаревшие сведения; с появлением более новых средств книги обновлялись, но, к сожалению, новая информация размещалась в конце.
Считаю, что такой подход неверен. В этой книге рассматриваются только современные подходы к реализации конкурентности. Это вовсе не значит, что понимание всех низкоуровневых концепций не принесет вам пользы. Когда я изучал программирование в колледже, на одном из курсов мне пришлось строить виртуальный процессор из набора элементарных логических вентилей, а на другом — изучать программирование на языке ассемблера. За всю профессиональную карьеру я не спроектировал ни одного процессора и написал всего пару десятков строк ассемблерного кода, но понимание основ приносит пользу ежедневно. И все же лучше начинать с высокоуровневых абстракций; на моем первом курсе программирования рассматривался вовсе не язык ассемблера.
Эта книга занимает определенную нишу: она содержит введение (и справочник) по конкурентности с использованием современных методов. В ней рассматриваются различные виды конкурентности, включая параллельную обработку, асинхронное и реактивное программирование. Тем не менее в ней не рассматриваются устаревшие методы, которые описаны в других книгах и сетевых ресурсах.
В этой книге приняты следующие типографские соглашения:
Курсив
Используется для обозначения новых терминов.
Моноширинныйшрифт
Применяется для оформления листингов программ и программных элементов внутри обычного текста, таких как имена переменных и функций, баз данных, типов данных, переменных окружения, инструкций и ключевых слов.
Так выделяются советы и предложения.
Так обозначаются предупреждения и предостережения.
Книга имеет следующую структуру:
• В главе 1 содержится введение в различные виды конкурентности, описанные в книге: параллелизм, асинхронное и реактивное программирование, потоки данных.
• В главах 2–6 представлено более подробное введение в разновидности конкурентности.
• В каждой из оставшихся глав рассматривается конкретный аспект конкурентности; они также могут рассматриваться как сборник решений типичных проблем.
Рекомендую прочитать (или по крайней мере просмотреть) первую главу, даже если вы уже знакомы с некоторыми разновидностями конкурентности.
На момент отправки книги в печать .NET Core 3.0 еще находится на стадии бета-тестирования, поэтому некоторые нюансы асинхронных потоков могут измениться.
Эта книга просто не смогла бы появиться без помощи множества людей!
Прежде всего хочу выразить благодарность своему Господу и Спасителю Иисусу Христу. Принятие христианства стало самым важным решением в моей жизни! Если вам понадобится дополнительная информация по этой теме, вы можете связаться со мной на моем сайте /.
Также я благодарен своей семье, простившей мне все то время, которое я мог бы провести с ней. Когда я начал работать над книгой, некоторые друзья говорили мне: «Попрощайся с семьей на следующий год!» Я думал, что они шутят. Моя жена Мэнди и наши дети Эс-Ди и Эмма проявляли понимание, когда я проводил долгие дни за работой, а потом писал по вечерам и выходным. Спасибо вам всем. Я люблю вас!
Конечно, эта книга была бы далеко не такой качественной, если бы не мои редакторы и научные редакторы: Стивен Тауб (Stephen Toub), Петр Ондерка (Petr Onderka) («svick»), Ник Палдино (Nick Paldino) («casperOne»), Ли Кэмпбелл (Lee Campbell) и Педро Феликс (Pedro Felix). И если в книгу прокрались какие-либо неточности — это целиком их вина… Шучу! Их мнение оказало неоценимую помощь в формировании (и исправлении) материала, а за все оставшиеся ошибки, конечно, отвечаю только я. Выражаю особую благодарность Стивену Таубу (Stephen Toub), который научил меня «трюку с логическим аргументом» (рецепт 14.5) и рассказал о бесчисленных нюансах, связанных с async, и Ли Кэмпбеллу (Lee Campbell), который помог мне освоить System.Reactive и сделать мой наблюдаемый код более идиоматическим.
Наконец, я хочу поблагодарить некоторых людей, от которых я узнал об этих методах: Стивена Тауба (Stephen Toub), Люциана Вищика (Lucian Wischik), Томаса Левеска (Thomas Levesque), Ли Кэмпбелла (Lee Campbell), сообщество Stack Overflow и форумов MSDN, а также участников конференций по программированию в моем родном штате Мичиган. Мне нравится быть частью сообщества разработчиков ПО, и если эта книга кому-то поможет, то стоит поблагодарить многих других, показавших правильный путь. Спасибо всем!
Ваши замечания, предложения, вопросы отправляйте по адресу (издательство «Питер», компьютерная редакция).
Мы будем рады узнать ваше мнение!
На веб-сайте издательства вы найдете подробную информацию о наших книгах.
Обратите внимание: по всей книге автор дает перекрестные ссылки на рецепты. Нумерованные подзаголовки в главах и являются этими рецептами.