День шестьсот девятнадцатый. #ЗаметкиНаПолях
Запуск Миграций EFCore из Вашего Кода
Все пользователи Entity Framework/EF Core знают, что запустить миграции из консоли или менеджера пакетов можно с помощью команды:
Миграция EF Core в C#
На самом деле все очень просто.
Проверка Ожидающих Миграций
Также может быть нужно проверить, есть ли ожидающие миграции, прежде чем пытаться их запустить. Например, может быть полезно узнать, в каком состоянии находится база данных, из панели администратора:
В некоторых случаях вам всё равно, когда выполняется миграция, вы просто хотите, перенести базу данных до запуска приложения. Это подойдёт для проектов, в которых время миграции базы данных не имеет значения или оно относительно небольшое. Например, для мало нагруженных веб-сайтов, расположенных на одном сервере. Для этого в .NET Core есть парадигма «Фильтров Запуска» (StartupFilter). Код будет примерно следующим:
Осталось добавить наш фильтр в контейнер DI в
Источник: https://dotnetcoretutorials.com/
Запуск Миграций EFCore из Вашего Кода
Все пользователи Entity Framework/EF Core знают, что запустить миграции из консоли или менеджера пакетов можно с помощью команды:
Update-DatabaseКроме того, можно использовать команду
dotnet ef
:dotnet ef database updateНо иногда может потребоваться запускать миграции по запросу из кода C#, например, вызвав конечную точку API из панели администратора сайта. Как правило, это было проблемой в более старых версиях Entity Framework, когда «версия» базы данных не совпадала с «версией» нужной EF Code. В этом случае «всё падало». В EF Core с этим меньше проблем, так как ваш код не рухнет, пока не попытается сделать что-то, что не может завершить (например, выбрать столбец, который ещё не существует). Но все же есть случаи, когда нужно развернуть код, протестировать его работу в промежуточной среде с действующей базой данных, а затем запустить миграцию базы данных по запросу.
Миграция EF Core в C#
На самом деле все очень просто.
var migrator = _context.Database.GetService<IMigrator>();Где
await migrator.MigrateAsync();
_context
– это контекст вашей базы данных.Проверка Ожидающих Миграций
Также может быть нужно проверить, есть ли ожидающие миграции, прежде чем пытаться их запустить. Например, может быть полезно узнать, в каком состоянии находится база данных, из панели администратора:
await _context.Database.GetPendingMigrationsAsync();Миграция При Запуске Приложения
В некоторых случаях вам всё равно, когда выполняется миграция, вы просто хотите, перенести базу данных до запуска приложения. Это подойдёт для проектов, в которых время миграции базы данных не имеет значения или оно относительно небольшое. Например, для мало нагруженных веб-сайтов, расположенных на одном сервере. Для этого в .NET Core есть парадигма «Фильтров Запуска» (StartupFilter). Код будет примерно следующим:
public class MigrationStartupFilter<TContext> :Фильтры запуска в .NET Core в основном похожи на фильтры в MVC. Они встраиваются в процесс запуска и выполняют код перед запуском приложения, причём только при запуске. Если вы когда-либо использовали
IStartupFilter where TContext : DbContext {
public Action<IApplicationBuilder>
Configure(Action<IApplicationBuilder> next) {
return app => {
using (var scope =
app.ApplicationServices.CreateScope()) {
foreach (var context in
scope.ServiceProvider.GetServices<TContext>()) {
context.Database.SetCommandTimeout(160);
context.Database.Migrate();
}
}
next(app);
};
}
}
Application_Start()
в global.asax
в .NET Framework, то это очень похоже.Осталось добавить наш фильтр в контейнер DI в
Startup.cs
:services.AddTransient<IStartupFilter,Здесь
MigrationStartupFilter<Context>>();
Context
- это контекст нашей базы данных.Источник: https://dotnetcoretutorials.com/
День шестьсот двадцатый. #Оффтоп #Курсы
Сегодня расскажу вам о нескольких предстоящих онлайн событиях, которые могут быть интересны разработчикам .NET. Пойдём в хронологическом порядке.
Решения SAP в Microsoft Azure
13 октября 2020г., начало в 10:00 (мск.)
Язык: русский
Темой вебинара станет переход на SAP S/4HANA в Microsoft Azure, который мгновенно обеспечивает компаниям гибкость и возможности для получения полезных сведений. Кроме того, такой переход упрощает будущее развитие инноваций и усовершенствование бизнес-процессов. Представители Microsoft и SAP расскажут, каким образом эти компании использовали SAP S/4HANA в Azure для трансформации собственных бизнес-процессов. Вы познакомитесь со всеми инфраструктурными предложениями от Microsoft Azure, которые базируются на новейших технологиях Intel и разработаны специально для SAP S/4HANA.
Pluralsight LIVE
13 октября 2020г., начало в 22:00 (мск.)
Язык: английский
Pluralsight LIVE - ежегодная конференция по технологическим навыкам, которая в этом году будет виртуальной. Microsoft представляет в этом году углублённое занятие, посвященное развитию навыков работы с Azure (Build your Azure skills with Microsoft Learn and Pluralsight). На этом занятии вы узнаете, как получить навыки, необходимые для решения задач современного облачного цифрового мира. Вы узнаете:
- что нового в Azure,
- как приобретение необходимых навыков в Azure может вам помочь использовать новейшие технологии,
- как работает совместное предложение от Microsoft Learn и Pluralsight,
- какие сертификаты подходят вам или вашей команде.
Основы проектирования защищённых облачных решений в Azure
16 октября 2020г., начало в 10:00 (мск.)
Язык: русский
Аспекты, связанные с безопасностью, нужно учитывать на протяжении всего жизненного цикла приложения — от разработки и реализации до развертывания и эксплуатации. Используйте подходы, описанные в Azure Well-Architected Framework для построения безопасных решений, способных противостоять современным киберугрозам.
В ходе этого вебинара вы узнаете об:
- Общих принципах проектирования защищённой облачной архитектуры.
- Ключевых рисках и требованиях безопасности.
- Подходах к проектированию защищённых систем управления удостоверениями и доступом, сетей, хранилищ и баз данных, приложений и служб.
- Практиках управления безопасностью.
State of .NET - .NET 5 Preview
28 октября 2020г.
Язык: английский
Очередной эпизод из серии вебинаров «State of .NET» от CODE Magazine. В нём расскажут о том, чего ожидать от предстоящего релиза .NET 5.
PS: Все вебинары бесплатны.
PPS: Pluralsight объявили неделю бесплатных курсов для новых подписчиков с 12 по 18 октября! Налетай!
Сегодня расскажу вам о нескольких предстоящих онлайн событиях, которые могут быть интересны разработчикам .NET. Пойдём в хронологическом порядке.
Решения SAP в Microsoft Azure
13 октября 2020г., начало в 10:00 (мск.)
Язык: русский
Темой вебинара станет переход на SAP S/4HANA в Microsoft Azure, который мгновенно обеспечивает компаниям гибкость и возможности для получения полезных сведений. Кроме того, такой переход упрощает будущее развитие инноваций и усовершенствование бизнес-процессов. Представители Microsoft и SAP расскажут, каким образом эти компании использовали SAP S/4HANA в Azure для трансформации собственных бизнес-процессов. Вы познакомитесь со всеми инфраструктурными предложениями от Microsoft Azure, которые базируются на новейших технологиях Intel и разработаны специально для SAP S/4HANA.
Pluralsight LIVE
13 октября 2020г., начало в 22:00 (мск.)
Язык: английский
Pluralsight LIVE - ежегодная конференция по технологическим навыкам, которая в этом году будет виртуальной. Microsoft представляет в этом году углублённое занятие, посвященное развитию навыков работы с Azure (Build your Azure skills with Microsoft Learn and Pluralsight). На этом занятии вы узнаете, как получить навыки, необходимые для решения задач современного облачного цифрового мира. Вы узнаете:
- что нового в Azure,
- как приобретение необходимых навыков в Azure может вам помочь использовать новейшие технологии,
- как работает совместное предложение от Microsoft Learn и Pluralsight,
- какие сертификаты подходят вам или вашей команде.
Основы проектирования защищённых облачных решений в Azure
16 октября 2020г., начало в 10:00 (мск.)
Язык: русский
Аспекты, связанные с безопасностью, нужно учитывать на протяжении всего жизненного цикла приложения — от разработки и реализации до развертывания и эксплуатации. Используйте подходы, описанные в Azure Well-Architected Framework для построения безопасных решений, способных противостоять современным киберугрозам.
В ходе этого вебинара вы узнаете об:
- Общих принципах проектирования защищённой облачной архитектуры.
- Ключевых рисках и требованиях безопасности.
- Подходах к проектированию защищённых систем управления удостоверениями и доступом, сетей, хранилищ и баз данных, приложений и служб.
- Практиках управления безопасностью.
State of .NET - .NET 5 Preview
28 октября 2020г.
Язык: английский
Очередной эпизод из серии вебинаров «State of .NET» от CODE Magazine. В нём расскажут о том, чего ожидать от предстоящего релиза .NET 5.
PS: Все вебинары бесплатны.
PPS: Pluralsight объявили неделю бесплатных курсов для новых подписчиков с 12 по 18 октября! Налетай!
День шестьсот двадцать первый. #BestPractices
6 Советов по Работе с Памятью в Приложениях .NET. Начало 1-2
Проблемы с памятью в большом .NET-приложении - своего рода тихий убийца. Как гипертония. Вы можете долго есть нездоровую пищу, игнорируя её, пока однажды не столкнетесь с серьезной проблемой. В случае программы .NET серьезной проблемой может быть высокое потребление памяти, проблемы с производительностью и сбои в работе.
Как узнать, правильно ли вы используете память? Что нужно делать, чтобы с ней не возникало проблем? Мы рассмотрим 6 рекомендаций, которые помогут сохранить память в рабочем состоянии и выявить проблемы, если они возникнут.
1. Объекты должны собираться сборщиком мусора как можно раньше
Чтобы ваша программа работала быстро, главная цель - как можно раньше уничтожать объекты. Чтобы понять, почему это важно, нужно иметь понятие о поколениях объектов в .NET. https://t.iss.one/NetDeveloperDiary/208 Когда объекты создаются с помощью new, они помещаются в куче в поколении 0. Это очень маленький объем памяти. Если после сборки мусора на них по-прежнему есть ссылки, они переводятся в поколение 1. Поколение 1 - это больший объем памяти. Если после следующей сборки мусора на них по-прежнему ссылаются, они переводятся в поколение 2.
Сборки мусора в поколении 0 производятся наиболее часто и очень быстро. Сборка в поколении 1 охватывает как пространства памяти как поколения 0, так и поколения 1, поэтому она более дорогая. Сборка в поколении 2 включает в себя всё пространство памяти, включая кучу больших объектов (LOH). Сборка мусора в поколении 2 очень дорогая. Сборщик мусора (GC) оптимизирован, чтобы проводить много сборок в поколении 0, меньше в поколении 1 и очень мало сборок в поколении 2. Но, если у вас много объектов, которые переходят в более высокое поколение, вы получите обратный эффект. Это приводит к нехватке памяти (также известной как давление на GC) и снижению производительности.
Кстати, размещение новых объектов обходится крайне дешево. Единственное, о чем нужно беспокоиться, - это сборка мусора.
Так как же держать объекты в младшем поколении? Просто убедитесь, что ссылки на них удаляются как можно раньше. Некоторые объекты, например одиночки, должны всегда оставаться в памяти. Ничего страшного, обычно это будут службы, которые в любом случае не потребляют много памяти.
2. Используйте кэширование… но осторожно
Такие механизмы, как кэширование, по определению проблемные. Это долговечные временные объекты, которые, скорее всего, будут переведены в поколение 2, хотя это плохо для сборщика мусора, но обычно стоит того, потому что кэширование действительно может улучшить производительность. Однако нужно следить за ним.
Один из способов уменьшить это давление на память - использовать изменяемые объекты кэша. Это означает, что вместо замены объекта кэша вы обновляете существующий объект. То есть у сборщика мусора будет меньше работы по продвижению объектов между поколениями и больше сборок мусора в поколениях 0 и 1.
Допустим, вы кэшируете товары интернет-магазина. У вас есть механизм кэширования, который хранит цены и информацию для фиксированного набора часто запрашиваемых товаров. Предположим, каждые 5 минут вы должны обновлять кэш из базы в случае изменения данных. Тогда вместо создания нового набора товаров просто изменяйте состояние существующих объектов.
Продолжение следует…
Источник: https://michaelscodingspot.com/application-memory-health/
6 Советов по Работе с Памятью в Приложениях .NET. Начало 1-2
Проблемы с памятью в большом .NET-приложении - своего рода тихий убийца. Как гипертония. Вы можете долго есть нездоровую пищу, игнорируя её, пока однажды не столкнетесь с серьезной проблемой. В случае программы .NET серьезной проблемой может быть высокое потребление памяти, проблемы с производительностью и сбои в работе.
Как узнать, правильно ли вы используете память? Что нужно делать, чтобы с ней не возникало проблем? Мы рассмотрим 6 рекомендаций, которые помогут сохранить память в рабочем состоянии и выявить проблемы, если они возникнут.
1. Объекты должны собираться сборщиком мусора как можно раньше
Чтобы ваша программа работала быстро, главная цель - как можно раньше уничтожать объекты. Чтобы понять, почему это важно, нужно иметь понятие о поколениях объектов в .NET. https://t.iss.one/NetDeveloperDiary/208 Когда объекты создаются с помощью new, они помещаются в куче в поколении 0. Это очень маленький объем памяти. Если после сборки мусора на них по-прежнему есть ссылки, они переводятся в поколение 1. Поколение 1 - это больший объем памяти. Если после следующей сборки мусора на них по-прежнему ссылаются, они переводятся в поколение 2.
Сборки мусора в поколении 0 производятся наиболее часто и очень быстро. Сборка в поколении 1 охватывает как пространства памяти как поколения 0, так и поколения 1, поэтому она более дорогая. Сборка в поколении 2 включает в себя всё пространство памяти, включая кучу больших объектов (LOH). Сборка мусора в поколении 2 очень дорогая. Сборщик мусора (GC) оптимизирован, чтобы проводить много сборок в поколении 0, меньше в поколении 1 и очень мало сборок в поколении 2. Но, если у вас много объектов, которые переходят в более высокое поколение, вы получите обратный эффект. Это приводит к нехватке памяти (также известной как давление на GC) и снижению производительности.
Кстати, размещение новых объектов обходится крайне дешево. Единственное, о чем нужно беспокоиться, - это сборка мусора.
Так как же держать объекты в младшем поколении? Просто убедитесь, что ссылки на них удаляются как можно раньше. Некоторые объекты, например одиночки, должны всегда оставаться в памяти. Ничего страшного, обычно это будут службы, которые в любом случае не потребляют много памяти.
2. Используйте кэширование… но осторожно
Такие механизмы, как кэширование, по определению проблемные. Это долговечные временные объекты, которые, скорее всего, будут переведены в поколение 2, хотя это плохо для сборщика мусора, но обычно стоит того, потому что кэширование действительно может улучшить производительность. Однако нужно следить за ним.
Один из способов уменьшить это давление на память - использовать изменяемые объекты кэша. Это означает, что вместо замены объекта кэша вы обновляете существующий объект. То есть у сборщика мусора будет меньше работы по продвижению объектов между поколениями и больше сборок мусора в поколениях 0 и 1.
Допустим, вы кэшируете товары интернет-магазина. У вас есть механизм кэширования, который хранит цены и информацию для фиксированного набора часто запрашиваемых товаров. Предположим, каждые 5 минут вы должны обновлять кэш из базы в случае изменения данных. Тогда вместо создания нового набора товаров просто изменяйте состояние существующих объектов.
Продолжение следует…
Источник: https://michaelscodingspot.com/application-memory-health/
День шестьсот двадцать второй. #BestPractices
6 Советов по Работе с Памятью в Приложениях .NET. Продолжение 3-4
Начало
3. Следите за процентом времени, затрачиваемым на сборку мусора
Если вы хотите узнать, насколько сборка мусора влияет на время выполнения программы, это довольно легко сделать. Просто посмотрите на счётчик производительности (Performance Monitor) .NET CLR Memory | % Time in GC. Он покажет, какой процент времени выполнения используется сборщиком мусора. Есть много инструментов для просмотра счетчиков производительности. В Windows вы можете использовать PerfMon. В Linux вы можете использовать dotnet-trace.
Далее приведены пара «магических чисел», но относитесь к ним с подозрением, потому что у каждого приложения свой контекст. Для большого приложения 10% времени в GC – это, скорее всего, нормальный процент. 20% времени в сборке мусора - это предел, а большее число означает, что у вас проблемы.
4. Следите за сборками мусора в поколении 2
Помимо процента времени на сборку мусора, другой полезной метрикой является количество сборок мусора в поколении 2. А точнее относительное количество сборок мусора в поколении 2. Задача состоит в том, чтобы их было как можно меньше. Учтите, что это полные сборки мусора во всей куче памяти. Они фактически замораживают все потоки приложения, пока сборщик мусора всё собирает.
Нельзя точно сказать, сколько сборок в поколении 2 у вас должно быть. Просто следите за их количеством, и, если этот показатель возрастает, вероятно, вы добавили какое-то нехорошее поведение. Вы можете посмотреть это число с помощью счётчика производительности .NET CLR Memory | % Gen 2 Collections (см. картинку ниже).
Окончание следует…
Источник: https://michaelscodingspot.com/application-memory-health/
6 Советов по Работе с Памятью в Приложениях .NET. Продолжение 3-4
Начало
3. Следите за процентом времени, затрачиваемым на сборку мусора
Если вы хотите узнать, насколько сборка мусора влияет на время выполнения программы, это довольно легко сделать. Просто посмотрите на счётчик производительности (Performance Monitor) .NET CLR Memory | % Time in GC. Он покажет, какой процент времени выполнения используется сборщиком мусора. Есть много инструментов для просмотра счетчиков производительности. В Windows вы можете использовать PerfMon. В Linux вы можете использовать dotnet-trace.
Далее приведены пара «магических чисел», но относитесь к ним с подозрением, потому что у каждого приложения свой контекст. Для большого приложения 10% времени в GC – это, скорее всего, нормальный процент. 20% времени в сборке мусора - это предел, а большее число означает, что у вас проблемы.
4. Следите за сборками мусора в поколении 2
Помимо процента времени на сборку мусора, другой полезной метрикой является количество сборок мусора в поколении 2. А точнее относительное количество сборок мусора в поколении 2. Задача состоит в том, чтобы их было как можно меньше. Учтите, что это полные сборки мусора во всей куче памяти. Они фактически замораживают все потоки приложения, пока сборщик мусора всё собирает.
Нельзя точно сказать, сколько сборок в поколении 2 у вас должно быть. Просто следите за их количеством, и, если этот показатель возрастает, вероятно, вы добавили какое-то нехорошее поведение. Вы можете посмотреть это число с помощью счётчика производительности .NET CLR Memory | % Gen 2 Collections (см. картинку ниже).
Окончание следует…
Источник: https://michaelscodingspot.com/application-memory-health/
День шестьсот двадцать третий. #BestPractices
6 Советов по Работе с Памятью в Приложениях .NET. Окончание 5-6
Начало
Продолжение
5. Следите за стабильностью потребления памяти.
Рассмотрим обычное состояние приложения. Некоторые события происходят постоянно. Это может быть сервер, обслуживающий запросы, служба, извлекающая сообщения из очереди, настольное приложение с множеством форм. В это время ваше приложение постоянно создаёт новые объекты, выполняет какие-то операции, а затем освобождает эти объекты и возвращается в нормальное состояние. Это означает, что потребление памяти должно быть более или менее одинаковым в долгосрочной перспективе. Конечно, оно может возрастать во время пиковых нагрузок или интенсивной обработки данных, но после этого оно должно возвращаться в нормальное состояние.
Но если у вас есть опыт подобного отслеживания приложений, вы, вероятно, знаете, что иногда объём потребляемой памяти со временем увеличивается. Среднее потребление медленно растёт, хотя по логике этого не должно быть. Причина такого поведения почти всегда - утечки памяти. Это происходит, когда объект больше не используется, но по какой-то причине на него всё ещё ссылаются и, следовательно, он никогда не попадает в сборку мусора.
Если операция вызывает утечку объектов, каждая такая операция увеличивает потребление памяти. Когда проходит достаточно времени, потребление памяти приближается к своему пределу. В 32-битном процессе этот предел составляет 4 ГБ. В 64-битном процессе это зависит от ограничений компьютера. Когда потребление памяти приближаемся к пределу, сборщик мусора паникует. Он начинает запускать полную сборку мусора при каждом выделении памяти, чтобы не исчерпать её совсем. Это может замедлить ваше приложение до скорости улитки. Однако в итоге потребление памяти таки достигает предела, и приложение аварийно завершает работу, выбрасывая OutOfMemoryException.
Чтобы убедиться, что с вашим приложением такого не случится, активно отслеживайте потребление памяти с течением времени. Лучший способ сделать это - посмотреть на счетчик производительности Process | Private Bytes. Вы можете легко сделать это с помощью Process Explorer или PerfMon.
6. Периодически ищите утечки памяти
Виновник проблем с памятью №1, без сомнения, - утечки памяти. Их легко вызвать, их можно долго игнорировать, но в итоге они наносят непоправимый ущерб. Устранять утечки памяти на этапе, когда ваше приложение систематически падает, очень сложно. Вам придётся в спешке менять код, что может приводить к разнообразным ошибкам. Поэтому очень важно вовремя вносить коррективы и избегать утечек памяти.
Нереально ожидать, что ваша команда никогда не их допустит утечек памяти. И нецелесообразно проверять их во всем приложении при каждом изменении. Вместо этого введите практику периодической проверки на утечки памяти. Это может быть еженедельно, ежемесячно или ежеквартально, как вам удобно.
Другой вариант проверять утечки памяти каждый раз, когда вы замечаете увеличение объема потребляемой памяти (как описано в совете №5). Но проблема в том, что даже небольшие утечки могут вызывать множество проблем. Например, у вас могут быть объекты, которые должны были быть собраны GC, но остаются живыми и в них продолжает исполняться какой-то код, что приводит к неправильному поведению.
Лучший способ обнаружить и исправить утечки памяти - использовать профилировщик памяти.
Источник: https://michaelscodingspot.com/application-memory-health/
6 Советов по Работе с Памятью в Приложениях .NET. Окончание 5-6
Начало
Продолжение
5. Следите за стабильностью потребления памяти.
Рассмотрим обычное состояние приложения. Некоторые события происходят постоянно. Это может быть сервер, обслуживающий запросы, служба, извлекающая сообщения из очереди, настольное приложение с множеством форм. В это время ваше приложение постоянно создаёт новые объекты, выполняет какие-то операции, а затем освобождает эти объекты и возвращается в нормальное состояние. Это означает, что потребление памяти должно быть более или менее одинаковым в долгосрочной перспективе. Конечно, оно может возрастать во время пиковых нагрузок или интенсивной обработки данных, но после этого оно должно возвращаться в нормальное состояние.
Но если у вас есть опыт подобного отслеживания приложений, вы, вероятно, знаете, что иногда объём потребляемой памяти со временем увеличивается. Среднее потребление медленно растёт, хотя по логике этого не должно быть. Причина такого поведения почти всегда - утечки памяти. Это происходит, когда объект больше не используется, но по какой-то причине на него всё ещё ссылаются и, следовательно, он никогда не попадает в сборку мусора.
Если операция вызывает утечку объектов, каждая такая операция увеличивает потребление памяти. Когда проходит достаточно времени, потребление памяти приближается к своему пределу. В 32-битном процессе этот предел составляет 4 ГБ. В 64-битном процессе это зависит от ограничений компьютера. Когда потребление памяти приближаемся к пределу, сборщик мусора паникует. Он начинает запускать полную сборку мусора при каждом выделении памяти, чтобы не исчерпать её совсем. Это может замедлить ваше приложение до скорости улитки. Однако в итоге потребление памяти таки достигает предела, и приложение аварийно завершает работу, выбрасывая OutOfMemoryException.
Чтобы убедиться, что с вашим приложением такого не случится, активно отслеживайте потребление памяти с течением времени. Лучший способ сделать это - посмотреть на счетчик производительности Process | Private Bytes. Вы можете легко сделать это с помощью Process Explorer или PerfMon.
6. Периодически ищите утечки памяти
Виновник проблем с памятью №1, без сомнения, - утечки памяти. Их легко вызвать, их можно долго игнорировать, но в итоге они наносят непоправимый ущерб. Устранять утечки памяти на этапе, когда ваше приложение систематически падает, очень сложно. Вам придётся в спешке менять код, что может приводить к разнообразным ошибкам. Поэтому очень важно вовремя вносить коррективы и избегать утечек памяти.
Нереально ожидать, что ваша команда никогда не их допустит утечек памяти. И нецелесообразно проверять их во всем приложении при каждом изменении. Вместо этого введите практику периодической проверки на утечки памяти. Это может быть еженедельно, ежемесячно или ежеквартально, как вам удобно.
Другой вариант проверять утечки памяти каждый раз, когда вы замечаете увеличение объема потребляемой памяти (как описано в совете №5). Но проблема в том, что даже небольшие утечки могут вызывать множество проблем. Например, у вас могут быть объекты, которые должны были быть собраны GC, но остаются живыми и в них продолжает исполняться какой-то код, что приводит к неправильному поведению.
Лучший способ обнаружить и исправить утечки памяти - использовать профилировщик памяти.
Источник: https://michaelscodingspot.com/application-memory-health/
День шестьсот двадцать четвёртый. #Книги
Несколько человек спрашивали в чате и в личке, какие книжки почитать, поэтому сделаю тут небольшую подборку.
Следующие книги распространяются свободно в PDF.
1. "Learn Azure in a Month of Lunches"
Быстрый старт в Azure в 21 уроке. В этой книге более 350 страниц, но лишь краткое описание всего того, что вы можете делать в Azure. В ней выборочно представлено только самое главное из того, чем вам может помочь Azure при создании приложений. Книга не охватывает все из более сотни сервисов Azure и не дает исчерпывающих подробностей о сервисах, которые включены в неё. Вместо этого она фокусируется на основных моментах некоторых основных сервисов и показывает примеры, как их безопасно соединить, а также знакомит с возможностями того, что вы можете создать в Azure.
Далее пара книг, которые представляют собой скомпилированную документацию Майкрософт:
2. "Architecting Modern Web Applications with ASP.NET Core and Azure"
В этом руководстве представлены комплексные рекомендации по созданию монолитных веб-приложений с использованием ASP.NET Core и Azure. Здесь понятие «монолитный» означает, что эти приложения развёртываются как единое целое, а не как набор взаимодействующих сервисов и приложений.
3. ".NET Microservices. Architecture for Containerized .NET Applications"
В противовес предыдущей книге, это введение в разработку приложений на основе микросервисов и управление ими с помощью контейнеров. Здесь обсуждаются подходы к архитектурному проектированию и реализации с использованием контейнеров .NET Core и Docker.
Ещё несколько недавно вышедших книг, которые советовали в чате. Их в PDF выкладывать не буду, чтобы не пиратить, мы тут люди приличные))) А, если очень хочется, гуглить все умеют, надеюсь ;)
4. Jason Alls "Clean Code in C#", Packt Publishing, 2020
Советы по рефакторингу легаси кода C# и улучшению производительности приложения применяя передовые практики. Вы узнаете, как определить проблемный код, который не обеспечивает читабельность, поддерживаемость и расширяемость. А также о различных инструментах, паттернах и способах рефакторинга кода, чтобы сделать его чистым.
5. Stephen Cleary "Concurrency in C# Cookbook: Asynchronous, Parallel, and Multithreaded Programming" 2nd Edition. O’Reilly, 2019.
Параллелизм - ключевой аспект красивого программного обеспечения. На протяжении десятилетий параллелизм был возможен, но труден: параллельное ПО было сложно писать, трудно отлаживать и поддерживать. В результате многие разработчики выбирали более простой путь и избегали параллелизма. Однако с библиотеками и языковыми функциями, доступными для современных программ .NET, параллелизм стал намного проще. Раньше параллельное программирование было прерогативой экспертов, в наши дни каждый разработчик может (и должен) использовать параллелизм.
Несколько человек спрашивали в чате и в личке, какие книжки почитать, поэтому сделаю тут небольшую подборку.
Следующие книги распространяются свободно в PDF.
1. "Learn Azure in a Month of Lunches"
Быстрый старт в Azure в 21 уроке. В этой книге более 350 страниц, но лишь краткое описание всего того, что вы можете делать в Azure. В ней выборочно представлено только самое главное из того, чем вам может помочь Azure при создании приложений. Книга не охватывает все из более сотни сервисов Azure и не дает исчерпывающих подробностей о сервисах, которые включены в неё. Вместо этого она фокусируется на основных моментах некоторых основных сервисов и показывает примеры, как их безопасно соединить, а также знакомит с возможностями того, что вы можете создать в Azure.
Далее пара книг, которые представляют собой скомпилированную документацию Майкрософт:
2. "Architecting Modern Web Applications with ASP.NET Core and Azure"
В этом руководстве представлены комплексные рекомендации по созданию монолитных веб-приложений с использованием ASP.NET Core и Azure. Здесь понятие «монолитный» означает, что эти приложения развёртываются как единое целое, а не как набор взаимодействующих сервисов и приложений.
3. ".NET Microservices. Architecture for Containerized .NET Applications"
В противовес предыдущей книге, это введение в разработку приложений на основе микросервисов и управление ими с помощью контейнеров. Здесь обсуждаются подходы к архитектурному проектированию и реализации с использованием контейнеров .NET Core и Docker.
Ещё несколько недавно вышедших книг, которые советовали в чате. Их в PDF выкладывать не буду, чтобы не пиратить, мы тут люди приличные))) А, если очень хочется, гуглить все умеют, надеюсь ;)
4. Jason Alls "Clean Code in C#", Packt Publishing, 2020
Советы по рефакторингу легаси кода C# и улучшению производительности приложения применяя передовые практики. Вы узнаете, как определить проблемный код, который не обеспечивает читабельность, поддерживаемость и расширяемость. А также о различных инструментах, паттернах и способах рефакторинга кода, чтобы сделать его чистым.
5. Stephen Cleary "Concurrency in C# Cookbook: Asynchronous, Parallel, and Multithreaded Programming" 2nd Edition. O’Reilly, 2019.
Параллелизм - ключевой аспект красивого программного обеспечения. На протяжении десятилетий параллелизм был возможен, но труден: параллельное ПО было сложно писать, трудно отлаживать и поддерживать. В результате многие разработчики выбирали более простой путь и избегали параллелизма. Однако с библиотеками и языковыми функциями, доступными для современных программ .NET, параллелизм стал намного проще. Раньше параллельное программирование было прерогативой экспертов, в наши дни каждый разработчик может (и должен) использовать параллелизм.
Если_бы_программисты_строили_дома.pdf
96.6 KB
День шестьсот двадцать пятый. #Юмор
Олды тут? Вон чего откопал в старых документах. Помню, дико популярны были такие «Хроники» в начале 2000х. Решил молодость вспомнить)))
Если понравится, пишите в комментариях, ещё выложу чего-нибудь. Хорошей пятницы.
https://telegra.ph/Esli-by-programmisty-stroili-doma-10-16
Олды тут? Вон чего откопал в старых документах. Помню, дико популярны были такие «Хроники» в начале 2000х. Решил молодость вспомнить)))
Если понравится, пишите в комментариях, ещё выложу чего-нибудь. Хорошей пятницы.
https://telegra.ph/Esli-by-programmisty-stroili-doma-10-16
День шестьсот двадцать шестой. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
63. Используйте Типы Специфичные для Домена Вместо Примитивных
23 сентября 1999г. Mars Climate Orbiter стоимостью 327,6 млн долларов был потерян при выходе на орбиту Марса из-за ошибки в программном обеспечении на Земле. Позднее выяснили, что перепутали единицы измерения. Программное обеспечение на Земле, поставленное компанией Локхид-Мартин, подавало команды аппарату, используя британские единицы силы фунты, в то время как космический корабль, сделанный в НАСА, ожидал принятые в системе СИ ньютоны. Из-за этого наземная станция недооценила мощность двигателей космического корабля почти в 4,5 раза. Эта неудача считается одной из причин окончательного и полного перехода NASA на метрическую систему, объявленного в 2007 году.
Это один из многих примеров сбоев программного обеспечения, которые можно было бы предотвратить, если бы применялась более строгая и специфичная для домена типизация. Это также объясняет наличие многих функций языка Ada, одной из основных целей разработки которого было создание программного обеспечения с высокими требованиями к безопасности. В Ada есть строгая типизация со статической проверкой как для примитивных, так и для определённых пользователем типов.
Если
а
Разработчики, работающие в менее требовательных к безопасности доменах, также могут извлечь выгоду из применения более специфичной для предметной области типизации, где в противном случае они могли бы продолжать использовать примитивные типы данных, такие как строки и числа с плавающей точкой. В Java, C++, C#, Python и других современных языках абстрактный тип данных известен как класс. Использование таких классов, как
- Код становится более читабельным, поскольку он выражает намерения в терминах домена, а не в виде общих Float или String.
- Код становится более тестируемым, поскольку легче тестировать инкапсулированное поведение.
- Упрощается повторное использование в приложениях и системах.
Этот подход одинаково применим как в статически, так и в динамически типизированных языках. Единственное отличие состоит в том, что разработчики, использующие языки со статической типизацией, получают некоторую помощь от компилятора, в то время как разработчики, использующие языки с динамической типизацией, с должны больше полагаться на модульные тесты. Стиль проверки может быть разным, но мотивация и стиль выражений - нет.
Мораль в том, что для повышения качества вашего программного обеспечения стоит использовать типы, специфичные для предметной области.
Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Einar Landre
97 Вещей, Которые Должен Знать Каждый Программист
63. Используйте Типы Специфичные для Домена Вместо Примитивных
23 сентября 1999г. Mars Climate Orbiter стоимостью 327,6 млн долларов был потерян при выходе на орбиту Марса из-за ошибки в программном обеспечении на Земле. Позднее выяснили, что перепутали единицы измерения. Программное обеспечение на Земле, поставленное компанией Локхид-Мартин, подавало команды аппарату, используя британские единицы силы фунты, в то время как космический корабль, сделанный в НАСА, ожидал принятые в системе СИ ньютоны. Из-за этого наземная станция недооценила мощность двигателей космического корабля почти в 4,5 раза. Эта неудача считается одной из причин окончательного и полного перехода NASA на метрическую систему, объявленного в 2007 году.
Это один из многих примеров сбоев программного обеспечения, которые можно было бы предотвратить, если бы применялась более строгая и специфичная для домена типизация. Это также объясняет наличие многих функций языка Ada, одной из основных целей разработки которого было создание программного обеспечения с высокими требованиями к безопасности. В Ada есть строгая типизация со статической проверкой как для примитивных, так и для определённых пользователем типов.
Если
VelocityInKnots
представляет собой Float
в диапазоне от 0.0
до 500.00
,а
DistanceInNauticalMiles
- Float
от 0.0
до 3000.00
, то следующий код:SomeNumber : Float;приведёт к ошибке компиляции.
SomeNumber := DistanceInNauticalMiles + VelocityInKnots;
Разработчики, работающие в менее требовательных к безопасности доменах, также могут извлечь выгоду из применения более специфичной для предметной области типизации, где в противном случае они могли бы продолжать использовать примитивные типы данных, такие как строки и числа с плавающей точкой. В Java, C++, C#, Python и других современных языках абстрактный тип данных известен как класс. Использование таких классов, как
VelocityInKnots
и DistanceInNauticalMiles
, серьёзно повысит качество кода:- Код становится более читабельным, поскольку он выражает намерения в терминах домена, а не в виде общих Float или String.
- Код становится более тестируемым, поскольку легче тестировать инкапсулированное поведение.
- Упрощается повторное использование в приложениях и системах.
Этот подход одинаково применим как в статически, так и в динамически типизированных языках. Единственное отличие состоит в том, что разработчики, использующие языки со статической типизацией, получают некоторую помощь от компилятора, в то время как разработчики, использующие языки с динамической типизацией, с должны больше полагаться на модульные тесты. Стиль проверки может быть разным, но мотивация и стиль выражений - нет.
Мораль в том, что для повышения качества вашего программного обеспечения стоит использовать типы, специфичные для предметной области.
Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Einar Landre
День шестьсот двадцать седьмой. #Оффтоп
Вот вам тема для воскресного обсуждения: «Как получить повышение в должности разработчика?»
Ниже приведу мой пересказ видео с ютуба (ссылка внизу). Все эти советы, конечно, элементарные, сферические в вакууме, взяты на примере западного рынка, поэтому не учитывают нашу специфику, и вообще, вроде бы проще переходить с повышением в другую компанию, и тэдэ, и тэпэ. Но это просто в качестве затравки.
1. Узнайте правила или критерии для повышения
Многие разработчики тратят огромные усилия, выполняя (и хорошо выполняя) работу, которая не расценивается в компании, как критерий для повышения. Если вы исправляете множество мелких недочётов в ПО, вы можете считать, что по количеству исправленных тикетов вы чемпион, но в компании могут цениться совсем другие качества. В гигантах, вроде FAGMA, есть чёткая градация уровней и список требований к квалификации на каждом уровне. В небольших компаниях вы можете прямо спросить об этом тимлида, начальника отдела или коллегу, которого недавно повысили.
2. Работайте на уровне, которого хотите достичь при повышении
Нет смысла быть высококлассным джуном. Нужно работать на уровне, требуемом от мидла, чтобы команда видела, что вы по факту превосходите уровень джуна. По мере роста вашей квалификации вам должно требоваться гораздо меньше подробностей в описании задачи, чтобы её выполнить. Джуну может требоваться описание, какие классы или таблицы БД создать, как реализовать тот или иной функционал. Более опытные разработчики принимают архитектурные и дизайнерские решения самостоятельно.
3. Ищите возможности
Чем выше должность в иерархии, тем объёмнее и серьёзнее задачи, которые выполняет специалист. Но и количество таких задач меньше. Как же их заполучить? Посещайте собрания, говорите с коллегами и менеджерами, предлагайте свои идеи. Проще говоря, повышайте софт скилы.
4. Не упускайте возможности
Не бойтесь нового, не бойтесь браться за незнакомые или сложные проекты (хотя, трезво оценивая свои силы, конечно). Но, если уж взялись, доводите дело до конца.
5. Дайте знать окружающим о своей работе
Этого разработчики обычно не любят, но без этого никуда. Ваши коллеги, а, главное, ваши начальники должны знать о том, что вы делаете и какие усилия вы прикладываете. Многие путают это с офисными интригами, подсиживанием коллег и присваиванием чужих результатов. Нет, не будьте такими. Здесь речь идёт исключительно о ваших заслугах и вашем вкладе в общее дело. Убедитесь, что ваши начальники в курсе. А это означает, что нужно поддерживать с ними связь и хорошие отношения. Снова софт скиллз.
6. Усердно работайте
«Спасибо, кэп», - скажете вы. Но факт остаётся фактом. Повышение – это не только «лычка» и больше денег, но и больше работы и ответственности. Повышения «за выслугу лет», конечно, случаются, но это скорее исключения.
В комментариях предлагаю вам описать свой опыт. Как вам удалось добиться повышения? Это было в крупной или небольшой компании? Какими советами вы можете поделиться?
Источник: https://www.youtube.com/watch?v=vm4OsDPK1gA
Вот вам тема для воскресного обсуждения: «Как получить повышение в должности разработчика?»
Ниже приведу мой пересказ видео с ютуба (ссылка внизу). Все эти советы, конечно, элементарные, сферические в вакууме, взяты на примере западного рынка, поэтому не учитывают нашу специфику, и вообще, вроде бы проще переходить с повышением в другую компанию, и тэдэ, и тэпэ. Но это просто в качестве затравки.
1. Узнайте правила или критерии для повышения
Многие разработчики тратят огромные усилия, выполняя (и хорошо выполняя) работу, которая не расценивается в компании, как критерий для повышения. Если вы исправляете множество мелких недочётов в ПО, вы можете считать, что по количеству исправленных тикетов вы чемпион, но в компании могут цениться совсем другие качества. В гигантах, вроде FAGMA, есть чёткая градация уровней и список требований к квалификации на каждом уровне. В небольших компаниях вы можете прямо спросить об этом тимлида, начальника отдела или коллегу, которого недавно повысили.
2. Работайте на уровне, которого хотите достичь при повышении
Нет смысла быть высококлассным джуном. Нужно работать на уровне, требуемом от мидла, чтобы команда видела, что вы по факту превосходите уровень джуна. По мере роста вашей квалификации вам должно требоваться гораздо меньше подробностей в описании задачи, чтобы её выполнить. Джуну может требоваться описание, какие классы или таблицы БД создать, как реализовать тот или иной функционал. Более опытные разработчики принимают архитектурные и дизайнерские решения самостоятельно.
3. Ищите возможности
Чем выше должность в иерархии, тем объёмнее и серьёзнее задачи, которые выполняет специалист. Но и количество таких задач меньше. Как же их заполучить? Посещайте собрания, говорите с коллегами и менеджерами, предлагайте свои идеи. Проще говоря, повышайте софт скилы.
4. Не упускайте возможности
Не бойтесь нового, не бойтесь браться за незнакомые или сложные проекты (хотя, трезво оценивая свои силы, конечно). Но, если уж взялись, доводите дело до конца.
5. Дайте знать окружающим о своей работе
Этого разработчики обычно не любят, но без этого никуда. Ваши коллеги, а, главное, ваши начальники должны знать о том, что вы делаете и какие усилия вы прикладываете. Многие путают это с офисными интригами, подсиживанием коллег и присваиванием чужих результатов. Нет, не будьте такими. Здесь речь идёт исключительно о ваших заслугах и вашем вкладе в общее дело. Убедитесь, что ваши начальники в курсе. А это означает, что нужно поддерживать с ними связь и хорошие отношения. Снова софт скиллз.
6. Усердно работайте
«Спасибо, кэп», - скажете вы. Но факт остаётся фактом. Повышение – это не только «лычка» и больше денег, но и больше работы и ответственности. Повышения «за выслугу лет», конечно, случаются, но это скорее исключения.
В комментариях предлагаю вам описать свой опыт. Как вам удалось добиться повышения? Это было в крупной или небольшой компании? Какими советами вы можете поделиться?
Источник: https://www.youtube.com/watch?v=vm4OsDPK1gA
День шестьсот двадцать восьмой. #ЗаметкиНаПолях #AsyncAwaitFAQ
Самые Частые Ошибки при Работе с async/await. Начало 1-4
1. Лишний async/await
Использование ключевых слов async/await приводит к неявному выделению памяти под конечный автомат, который отвечает за организацию асинхронных вызовов. Когда ожидаемое выражение является единственным или последним оператором в функции, его можно пропустить. Однако с этим есть несколько проблем, о которых вам следует знать.
❌ Неверно
Если мы используем асинхронный код, мы всегда должны использовать асинхронные методы, если они существуют. Многие API предлагают асинхронные аналоги своих хорошо известных синхронных методов.
❌ Неверно
Есть две причины, по которым
- Вызывающий код не может ожидать метод
- Невозможно обработать исключение, вызванное этим методом. Если возникает исключение, ваш процесс падает!
Вы всегда должны использовать
❌ Неверно
Если передать асинхронную лямбда-функцию в качестве аргумента типа
- изменить тип параметра с
- реализовать этот делегат синхронно.
Стоит отметить, что некоторые API-интерфейсы уже предоставляют аналоги своих методов, которые принимают
Источник: https://cezarypiatek.github.io/post/async-analyzers-p1/
Самые Частые Ошибки при Работе с async/await. Начало 1-4
1. Лишний async/await
Использование ключевых слов async/await приводит к неявному выделению памяти под конечный автомат, который отвечает за организацию асинхронных вызовов. Когда ожидаемое выражение является единственным или последним оператором в функции, его можно пропустить. Однако с этим есть несколько проблем, о которых вам следует знать.
❌ Неверно
async Task DoSomethingAsync(){✅ Верно
await Task.Yield();
}
Task DoSomethingAsync() {2. Вызов синхронного метода внутри асинхронного метода
return Task.Yield();
}
Если мы используем асинхронный код, мы всегда должны использовать асинхронные методы, если они существуют. Многие API предлагают асинхронные аналоги своих хорошо известных синхронных методов.
❌ Неверно
async Task DoAsync(Stream file, byte[] buffer) {✅ Верно
file.Read(buffer, 0, 10);
}
async Task DoAsync(Stream file, byte[] buffer) {3. Использование async void
await file.ReadAsync(buffer, 0, 10);
}
Есть две причины, по которым
async void
вреден:- Вызывающий код не может ожидать метод
async void
.- Невозможно обработать исключение, вызванное этим методом. Если возникает исключение, ваш процесс падает!
Вы всегда должны использовать
async Task
вместо async void
, если только это не обработчик событий, но тогда вы должны гарантировать себе, что метод не выбросит исключения.❌ Неверно
async void DoSomethingAsync() {✅ Верно
await Task.Yield();
}
async Task DoSomethingAsync() {4. Неподдерживаемые асинхронные делегаты
await Task.Yield();
}
Если передать асинхронную лямбда-функцию в качестве аргумента типа
Action
, компилятор сгенерирует метод async void
, недостатки которого были описаны выше. Есть два решения этой проблемы:- изменить тип параметра с
Action
на Func<Task>
, - реализовать этот делегат синхронно.
Стоит отметить, что некоторые API-интерфейсы уже предоставляют аналоги своих методов, которые принимают
Func<Task>.
void DoSomething() {
Callback(async() => {
await Task.Yield();
});
}
❌ Неверноvoid Callback(Action action){…}✅ Верно
void Callback(Func<Task> action){…}Продолжение следует…
Источник: https://cezarypiatek.github.io/post/async-analyzers-p1/
👍1
День шестьсот двадцать девятый. #ЗаметкиНаПолях #AsyncAwaitFAQ
Самые Частые Ошибки при Работе с async/await. Продолжение 5-7
Начало
5. Не ожидать Task в выражении using
❌ Неверно
Если мы пропустим ключевое слово
❌ Неверно
Отсутствие ключевого слова await перед асинхронной операцией приведет к завершению метода до завершения данной асинхронной операции. Метод будет вести себя непредсказуемо, и результат будет отличаться от ожиданий. Ещё хуже, если неожидаемое выражение выбросит исключение. Оно остается незамеченным и не вызовет сбоя процесса, что ещё больше затруднит его обнаружение. Вы всегда должны ожидать асинхронное выражение или присвоить возвращаемую задачу переменной и убедиться, что в итоге она где-то ожидается.
❌ Неверно
Источник: https://cezarypiatek.github.io/post/async-analyzers-p1/
Самые Частые Ошибки при Работе с async/await. Продолжение 5-7
Начало
5. Не ожидать Task в выражении using
System.Threading.Tasks.Task
реализует интерфейс IDisposable
. Вызов метода, возвращающего Task
, непосредственно в выражении using приводит к удалению задачи в конце блока using
, что никогда не является ожидаемым поведением.❌ Неверно
using (CreateDisposableAsync()) {✅ Верно
…
}
using (await CreateDisposableAsync()) {6. Не ожидать Task в блоке using
…
}
Если мы пропустим ключевое слово
await
для асинхронной операции внутри блока using
, то объект может быть удалён до завершения асинхронного вызова. Это приведёт к неправильному поведению и очень часто заканчивается исключением времени выполнения, сообщающим о том, что мы пытаемся работать с уже удалённым объектом.❌ Неверно
private Task<int> DoSomething() {✅ Верно
using (var service = CreateService()) {
return service.GetAsync();
}
}
private async Task<int> DoSomething() {7. Не ожидать результата асинхронного метода
using (var service = CreateService()) {
return await service.GetAsync();
}
}
Отсутствие ключевого слова await перед асинхронной операцией приведет к завершению метода до завершения данной асинхронной операции. Метод будет вести себя непредсказуемо, и результат будет отличаться от ожиданий. Ещё хуже, если неожидаемое выражение выбросит исключение. Оно остается незамеченным и не вызовет сбоя процесса, что ещё больше затруднит его обнаружение. Вы всегда должны ожидать асинхронное выражение или присвоить возвращаемую задачу переменной и убедиться, что в итоге она где-то ожидается.
❌ Неверно
async Task DoSomethingAsync() {✅ Верно
await DoSomethingAsync1();
DoSomethingAsync2();
await DoSomethingAsync3();
}
async Task DoSomethingAsync() {Продолжение следует…
await DoSomethingAsync1();
await DoSomethingAsync2();
await DoSomethingAsync3();
}
Источник: https://cezarypiatek.github.io/post/async-analyzers-p1/
День шестьсот тридцатый. #ЗаметкиНаПолях #AsyncAwaitFAQ
Самые Частые Ошибки при Работе с async/await. Продолжение 8-10
Начало
Часть 2
8. Синхронные ожидания
Если вы хотите ожидать асинхронное выражение в синхронном методе, вы должны переписать всю цепочку вызовов на асинхронную. Кажется, что более легкое решение - вызвать
❌ Неверно
По умолчанию, когда мы ожидаем асинхронную операцию, продолжение планируется с использованием захваченного
❌ Неверно
Возврат
❌ Неверно
Источник: https://cezarypiatek.github.io/post/async-analyzers-p2/
Самые Частые Ошибки при Работе с async/await. Продолжение 8-10
Начало
Часть 2
8. Синхронные ожидания
Если вы хотите ожидать асинхронное выражение в синхронном методе, вы должны переписать всю цепочку вызовов на асинхронную. Кажется, что более легкое решение - вызвать
Wait
или Result
для возвращаемой задачи. Но это будет стоить вам заблокированного потока и может привести к взаимной блокировке. Сделайте всю цепочку асинхронной. В консольном приложении допустим асинхронный метод Main, в контроллерах ASP.NET – асинхронные методы действия.❌ Неверно
void DoSomething() {✅ Верно
Thread.Sleep(1);
Task.Delay(2).Wait();
var result1 = GetAsync().Result;
var result2 = GetAsync().GetAwaiter().
GetResult();
var unAwaitedResult3 = GetAsync();
var result3 = unAwaitedResult3.Result;
}
async Task DoSomething() {9. Отсутствие ConfigureAwait(bool)
await Task.Delay(1);
await Task.Delay(2);
var result1 = await GetAsync();
var result2 = await GetAsync();
}
По умолчанию, когда мы ожидаем асинхронную операцию, продолжение планируется с использованием захваченного
SynchronizationContext
или TaskScheduler
. Это приводит к дополнительным затратам и может привести к взаимной блокировке, особенно в WindowsForms, WPF и старых приложениях ASP.NET. Вызывая ConfigureAwait(false)
, мы гарантируем, что текущий контекст игнорируется при вызове продолжения. Подробнее о ConfigureAwait
в серии постов с тегом #AsyncAwaitFAQ❌ Неверно
async Task DoSomethingAsync() {✅ Верно
await DoSomethingElse();
}
async Task DoSomethingAsync() {10. Возврат null из метода, возвращающего Task
await DoSomethingElse().
ConfigureAwait(false);
}
Возврат
null
значения из синхронного метода типа Task
/Task<>
приводит к исключению NullReferenceException
, если кто-то ожидает этот метод. Чтобы этого избежать, всегда возвращайте результат этого метода с помощью помощников Task.CompletedTask
или Task.FromResult<T>(null)
.❌ Неверно
Task DoAsync() {✅ Верно
return null;
}
Task<object> GetSomethingAsync() {
return null;
}
Task<HttpResponseMessage>
TryGetAsync(HttpClient httpClient) {
return httpClient?.
GetAsync("/some/endpoint");
}
Task DoAsync() {Продолжение следует…
return Task.CompletedTask;
}
Task<object> GetSomethingAsync() {
return Task.FromResult<object>(null);
}
Task<HttpResponseMessage>
TryGetAsync(HttpClient httpClient) {
return httpClient?.
GetAsync("/some/endpoint") ??
Task.FromResult(default(
HttpResponseMessage));
}
Источник: https://cezarypiatek.github.io/post/async-analyzers-p2/
День шестьсот тридцать первый. #ЗаметкиНаПолях #AsyncAwaitFAQ
Самые Частые Ошибки при Работе с async/await. Продолжение 11-13
Начало
Часть 2
Часть 3
11. Передача токена отмены
Если вы забудете передать токен отмены, это может привести к большим проблемам. Запущенная длительная операция без токена отмены может заблокировать действие по остановке приложения или привести к нехватке потоков при большом количестве отменённых веб-запросов. Чтобы избежать этого, всегда создавайте и передавайте токен отмены методам, которые его принимают, даже если это необязательный параметр.
❌ Неверно
Эта ошибка похожа на предыдущую, но относится исключительно к
❌ Неверно
И наоборот, имена синхронных методов не должны заканчиваться на
❌ Неверно
Источник: https://cezarypiatek.github.io/post/async-analyzers-p2/
Самые Частые Ошибки при Работе с async/await. Продолжение 11-13
Начало
Часть 2
Часть 3
11. Передача токена отмены
Если вы забудете передать токен отмены, это может привести к большим проблемам. Запущенная длительная операция без токена отмены может заблокировать действие по остановке приложения или привести к нехватке потоков при большом количестве отменённых веб-запросов. Чтобы избежать этого, всегда создавайте и передавайте токен отмены методам, которые его принимают, даже если это необязательный параметр.
❌ Неверно
public async Task<string>✅ Верно
GetSomething(HttpClient http) {
var response = await
http.GetAsync(new Uri("/endpoint/"));
return await
response.Content.ReadAsStringAsync();
}
public async Task<string>12. Использование токена отмены с IAsyncEnumerable
GetSomething(HttpClient http,
CancellationToken ct) {
var response = await
http.GetAsync(new Uri("/endpoint/"),
ct);
return await
response.Content.ReadAsStringAsync();
}
Эта ошибка похожа на предыдущую, но относится исключительно к
IAsyncEnumerable
и её довольно легко допустить. Это может быть неочевидно, но передача токена отмены в асинхронный перечислитель выполняется путем вызова метода WithCancellation()
.❌ Неверно
async Task Iterate(✅ Верно
IAsyncEnumerable<string> e) {
await foreach (var item in e) {
…
}
}
async Task Iterate(13. Имена асинхронных методов должны заканчиваться на Async
IAsyncEnumerable<string> e,
CancellationToken ct) {
await foreach (var item in
e.WithCancellation(ct))
{
…
}
}
И наоборот, имена синхронных методов не должны заканчиваться на
Async
. Так обычно происходит при невнимательном рефакторинге. Это не строгое обязательство и не ошибка. Вообще, это соглашение об именовании имеет смысл только тогда, когда класс предоставляет как синхронные, так и асинхронные версии метода.❌ Неверно
async Task DoSomething() {✅ Верно
await Task.Yield();
}
async Task DoSomethingAsync() {Продолжение следует…
await Task.Yield();
}
Источник: https://cezarypiatek.github.io/post/async-analyzers-p2/
День шестьсот тридцать второй. #ЗаметкиНаПолях #AsyncAwaitFAQ
Самые Частые Ошибки при Работе с async/await. Продолжение 14-16
Начало
Часть 2
Часть 3
Часть 4
14. Злоупотребление Task.Run в простых случаях
Для предварительно вычисленных или легко вычисляемых результатов нет необходимости вызывать
❌ Неверно
Хотя методы продолжений по-прежнему можно использовать, обычно рекомендуется использовать async/await вместо
❌ Неверно
Конструкторы синхронны. Если вам нужно инициализировать некоторую логику, которая может быть асинхронной, использование
Источник: https://github.com/davidfowl/AspNetCoreDiagnosticScenarios/blob/master/AsyncGuidance.md
Самые Частые Ошибки при Работе с async/await. Продолжение 14-16
Начало
Часть 2
Часть 3
Часть 4
14. Злоупотребление Task.Run в простых случаях
Для предварительно вычисленных или легко вычисляемых результатов нет необходимости вызывать
Task.Run
, который поставит задачу в очередь пула потоков, а задача немедленно завершится. Вместо этого используйте Task.FromResult
, чтобы создать задачу, обёртывающую уже вычисленный результат.❌ Неверно
public Task<int> AddAsync(int a, int b) {✅ Верно
return Task.Run(() => a + b);
}
public Task<int> AddAsync(int a, int b) {15. Await лучше, чем ContinueWith
return Task.FromResult(a + b);
}
Хотя методы продолжений по-прежнему можно использовать, обычно рекомендуется использовать async/await вместо
ContinueWith
. Кроме того, надо отметить, что ContinueWith
не захватывает SynchronizationContext
и поэтому семантически отличается от async/await.❌ Неверно
public Task<int> DoSomethingAsync() {✅ Верно
return CallDependencyAsync()
.ContinueWith(task => {
return task.Result + 1;
});
}
public async Task<int> DoSomethingAsync() {16. Синхронизация асинхронного кода в конструкторах
var result =
await CallDependencyAsync();
return result + 1;
}
Конструкторы синхронны. Если вам нужно инициализировать некоторую логику, которая может быть асинхронной, использование
Task.Result
для синхронизации в конструкторе может привести к истощению пула потоков и взаимным блокировкам. Лучше использовать статическую фабрику.public interface IRemoteConnFactory {❌ Неверно
Task<IRemoteConn> ConnectAsync();
}
public interface IRemoteConn { … }
public class Service : IService {✅ Верно
private readonly IRemoteConn _conn;
public Service(IRemoteConnFactory cf) {
_conn = cf.ConnectAsync().Result;
}
}
public class Service : IService {Окончание следует…
private readonly IRemoteConn _conn;
private Service(IRemoteConn conn) {
_conn = conn;
}
public static async Task<Service>
CreateAsync(IRemoteConnFactory cf)
{
return new Service(
await cf.ConnectAsync());
}
}
…
var cf = new ConnFactory();
var srv = await Service.CreateAsync(cf);
Источник: https://github.com/davidfowl/AspNetCoreDiagnosticScenarios/blob/master/AsyncGuidance.md
День шестьсот тридцать третий. #ЗаметкиНаПолях #AsyncAwaitFAQ
Анализаторы кода для асинхронного программирования
Большинство ошибок, описанных в предыдущих постах, можно обнаружить с помощью анализаторов кода, представленных в следующих пакетах. Многие из них не ограничены поиском ошибок в асинхронном коде, поэтому для каждого приведены правила, проверяющие перечисленные ранее ошибки.
1. Microsoft.CodeAnalysis.FxCopAnalyzers
CA2007 - Consider calling ConfigureAwait on the awaited task
CA2008 - Do not create tasks without passing a TaskScheduler
Полный список правил
2. Microsoft.VisualStudio.Threading.Analyzers
VSTHRD002 - Avoid problematic synchronous waits
VSTHRD100 - Avoid async void methods
VSTHRD101 - Avoid unsupported async delegates
VSTHRD107 - Await Task within using expression
VSTHRD111 - Use .ConfigureAwait(bool)
VSTHRD112 - Implement System.IAsyncDisposable
VSTHRD114 - Avoid returning null from a Task-returning method
VSTHRD200 - Use Async naming convention
Полный список правил
3. AsyncFixer
AsyncFixer01 - Unnecessary async/await usage
AsyncFixer03 - Fire & forget async void methods
AsyncFixer04 - Fire & forget async call inside a using block
Полный список правил
4. Roslyn.Analyzers
ASYNC0001 - Asynchronous method names should end with Async
ASYNC0002 - Non asynchronous method names shouldn’t end with Async
ASYNC0003 - Avoid void returning asynchronous method
ASYNC0004 - Use ConfigureAwait(false) on await expression
Полный список правил
5. Meziantou.Analyzer
MA0004 - Use .ConfigureAwait(false)
MA0022 - Return Task.FromResult instead of returning null
MA0032 - Use an overload that have cancellation token
MA0040 - Flow the cancellation token when available
MA0045 - Do not use blocking call (make method async)
MA0079 - Flow a cancellation token using .WithCancellation()
MA0080 - Specify a cancellation token using .WithCancellation()
Полный список правил
6. Roslynator
RCS1046 - Asynchronous method name should end with Async
RCS1047 - Non-asynchronous method name should not end with Async
RCS1090 - Call ConfigureAwait(false)
RCS1174 - Remove redundant async/await
RCS1210 - Return Task.FromResult instead of returning null
RCS1229 - Use async/await when necessary
Полный список правил
7. Asyncify
AsyncifyInvocation - This invocation could benefit from the use of Task async
AsyncifyVariable - This variable access could benefit from the use of Task async
Источник: https://cezarypiatek.github.io/post/async-analyzers-p1/
Анализаторы кода для асинхронного программирования
Большинство ошибок, описанных в предыдущих постах, можно обнаружить с помощью анализаторов кода, представленных в следующих пакетах. Многие из них не ограничены поиском ошибок в асинхронном коде, поэтому для каждого приведены правила, проверяющие перечисленные ранее ошибки.
1. Microsoft.CodeAnalysis.FxCopAnalyzers
CA2007 - Consider calling ConfigureAwait on the awaited task
CA2008 - Do not create tasks without passing a TaskScheduler
Полный список правил
2. Microsoft.VisualStudio.Threading.Analyzers
VSTHRD002 - Avoid problematic synchronous waits
VSTHRD100 - Avoid async void methods
VSTHRD101 - Avoid unsupported async delegates
VSTHRD107 - Await Task within using expression
VSTHRD111 - Use .ConfigureAwait(bool)
VSTHRD112 - Implement System.IAsyncDisposable
VSTHRD114 - Avoid returning null from a Task-returning method
VSTHRD200 - Use Async naming convention
Полный список правил
3. AsyncFixer
AsyncFixer01 - Unnecessary async/await usage
AsyncFixer03 - Fire & forget async void methods
AsyncFixer04 - Fire & forget async call inside a using block
Полный список правил
4. Roslyn.Analyzers
ASYNC0001 - Asynchronous method names should end with Async
ASYNC0002 - Non asynchronous method names shouldn’t end with Async
ASYNC0003 - Avoid void returning asynchronous method
ASYNC0004 - Use ConfigureAwait(false) on await expression
Полный список правил
5. Meziantou.Analyzer
MA0004 - Use .ConfigureAwait(false)
MA0022 - Return Task.FromResult instead of returning null
MA0032 - Use an overload that have cancellation token
MA0040 - Flow the cancellation token when available
MA0045 - Do not use blocking call (make method async)
MA0079 - Flow a cancellation token using .WithCancellation()
MA0080 - Specify a cancellation token using .WithCancellation()
Полный список правил
6. Roslynator
RCS1046 - Asynchronous method name should end with Async
RCS1047 - Non-asynchronous method name should not end with Async
RCS1090 - Call ConfigureAwait(false)
RCS1174 - Remove redundant async/await
RCS1210 - Return Task.FromResult instead of returning null
RCS1229 - Use async/await when necessary
Полный список правил
7. Asyncify
AsyncifyInvocation - This invocation could benefit from the use of Task async
AsyncifyVariable - This variable access could benefit from the use of Task async
Источник: https://cezarypiatek.github.io/post/async-analyzers-p1/
День шестьсот тридцать четвёртый. #Оффтоп
В прошлое воскресенье мы с вами говорили о повышении, сегодня наоборот, поговорим о том, чего не стоит делать, чтобы не пришлось обновлять резюме. Поводом послужило видео от Сергея Немчинского (ссылка ниже). Здесь опишу суть с краткими комментариями.
Опустим причины, которые вас не касаются, вроде закрытия компании, отдела, сокращения штата и т.д., и т.п. Обсудим только то, что зависит от вас.
Нанимать нового программиста дорого, поэтому просто так, без веских причин, вас вряд ли «попросят». Скорее неугодного человека переведут на малозначимую, скучную работу, которую кто-то должен делать, но тратить время хороших специалистов на неё жалко. Поэтому, если вы обнаружили себя на таком месте, есть повод задуматься.
Пять причин увольнения программистов
1. Ложь
Это, по-моему, самая веская причина увольнения программистов. В нашей сфере очень много построено на доверии, поэтому если человека ловят на обмане, работать с ним будет невозможно. Моего коллегу уволили ровно за это. Работали удалённо, с ним несколько раз за день пытались связаться, он не отвечал, а потом написал, что работал все 8 часов в этот день. Это, как говорят у них, "a big no-no".
2. Софт скилы
Как обычно, всё решают человеческие отношения. Неумение взаимодействовать с коллегами и руководством, токсичность, неумение отстоять свои идеи, и т.д. Если с вами по-человечески неприятно работать, вас либо задвинут на нудную работу, либо, в худшем случае, с вами попрощаются.
3. Несоответствие ожиданиям
Это скорее ошибка найма, когда принимают человека, явно не соответствующего требуемой квалификации, или когда хотят, чтобы новенький работал точно так же, как его предшественник. Тут не будет вашей вины, если только не… см. пункт 1. Если вы при найме сказали, что в совершенстве владеете тем, о чём понятия не имеете, уж не обессудьте.
4. Нарушение NDA
Ещё одна из вариаций лжи. Вы соглашаетесь с неразглашением информации, подписываете документ, а потом нарушаете договор. Учтите, что особенно в западных компаниях к этому относятся очень серьёзно.
5. Хард скилы
Здесь проблема скорее не в как таковом незнании чего-то, а в неумении или нежелании научиться этому. Но всё-таки, в нашей профессии это встречается довольно редко.
Подробности по ссылке ниже. Давайте обсудим. За что увольняливас… нет, конечно, не вас, ваших коллег или знакомых?
Источник: https://www.youtube.com/watch?v=QUr4NS-UQK4
В прошлое воскресенье мы с вами говорили о повышении, сегодня наоборот, поговорим о том, чего не стоит делать, чтобы не пришлось обновлять резюме. Поводом послужило видео от Сергея Немчинского (ссылка ниже). Здесь опишу суть с краткими комментариями.
Опустим причины, которые вас не касаются, вроде закрытия компании, отдела, сокращения штата и т.д., и т.п. Обсудим только то, что зависит от вас.
Нанимать нового программиста дорого, поэтому просто так, без веских причин, вас вряд ли «попросят». Скорее неугодного человека переведут на малозначимую, скучную работу, которую кто-то должен делать, но тратить время хороших специалистов на неё жалко. Поэтому, если вы обнаружили себя на таком месте, есть повод задуматься.
Пять причин увольнения программистов
1. Ложь
Это, по-моему, самая веская причина увольнения программистов. В нашей сфере очень много построено на доверии, поэтому если человека ловят на обмане, работать с ним будет невозможно. Моего коллегу уволили ровно за это. Работали удалённо, с ним несколько раз за день пытались связаться, он не отвечал, а потом написал, что работал все 8 часов в этот день. Это, как говорят у них, "a big no-no".
2. Софт скилы
Как обычно, всё решают человеческие отношения. Неумение взаимодействовать с коллегами и руководством, токсичность, неумение отстоять свои идеи, и т.д. Если с вами по-человечески неприятно работать, вас либо задвинут на нудную работу, либо, в худшем случае, с вами попрощаются.
3. Несоответствие ожиданиям
Это скорее ошибка найма, когда принимают человека, явно не соответствующего требуемой квалификации, или когда хотят, чтобы новенький работал точно так же, как его предшественник. Тут не будет вашей вины, если только не… см. пункт 1. Если вы при найме сказали, что в совершенстве владеете тем, о чём понятия не имеете, уж не обессудьте.
4. Нарушение NDA
Ещё одна из вариаций лжи. Вы соглашаетесь с неразглашением информации, подписываете документ, а потом нарушаете договор. Учтите, что особенно в западных компаниях к этому относятся очень серьёзно.
5. Хард скилы
Здесь проблема скорее не в как таковом незнании чего-то, а в неумении или нежелании научиться этому. Но всё-таки, в нашей профессии это встречается довольно редко.
Подробности по ссылке ниже. Давайте обсудим. За что увольняли
Источник: https://www.youtube.com/watch?v=QUr4NS-UQK4
День шестьсот тридцать пятый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
64. Предотвращайте Ошибки
Сообщения об ошибках - наиболее важные взаимодействия между пользователем и системой. Легко представить ошибку, вызванную неправильным вводом данных пользователем. Но люди систематически совершают вполне предсказуемые виды ошибок. Поэтому можно «отладить» связь между пользователем и системой так же, как и между компонентами системы.
Предположим, вы хотите, чтобы пользователь ввёл дату в допустимом диапазоне. Вместо того, чтобы позволять пользователю вводить любую дату, лучше предложить компонент UI вроде списка или календаря, предлагающего только разрешённые даты. Тогда ввести неверную дату будет невозможно.
Ошибки форматирования - ещё одна распространённая проблема. Например, пользователю предоставляется текстовое поле для ввода даты, и он вводит «
Такие ошибки возникают из-за того, что легче отклонить дату, чем проанализировать три или четыре наиболее распространённых формата даты и приводить их к нужному формату в программе. Подобные мелкие «недочёты» раздражают пользователя, что, в свою очередь, приводит к новым ошибкам, поскольку пользователь теряет концентрацию. Уважайте желание пользователей вводить информацию, а не данные.
Другой способ избежать ошибок форматирования - добавить подсказки. Например, с помощью метки в поле, показывающей желаемый формат («
Есть два способа сообщить пользователю, как правильно ввести информацию: инструкции и подсказки. Подсказки кратки и отображаются в точке ввода информации, инструкции более подробны и обычно располагаются перед формой.
Как правило, инструкции не помогают предотвратить ошибку. Пользователи склонны предполагать, что интерфейс будет работать в соответствии с их прошлым опытом («Конечно, все знают, что означает «26.10.2020»). Так что инструкции остаются непрочитанными. Подсказки более полезны в предотвращении ошибок.
Другой способ избежать ошибок - предложить значения по умолчанию. Например, пользователи обычно вводят значения даты, соответствующие сегодняшнему дню, завтрашнему дню, их дню рождения, ранее введённой дате и т.п. В зависимости от контекста одно из этих значений, вероятно, будет хорошим выбором по умолчанию.
Какой бы ни была причина, системы должны снисходительно относиться к ошибкам пользователей. Помимо описанного выше, можно предоставить пользователю несколько уровней отмены действий, особенно тех, которые могут уничтожить или изменить данные пользователя.
Регистрация и анализ действий отмены также может выявить, где интерфейс провоцирует пользователей на ошибки, вроде постоянных нажатий «неправильной» кнопки. Эти ошибки часто возникают из-за вводящих в заблуждение подсказок или последовательности действий, которую можно изменить, чтобы предотвратить такие ошибки в дальнейшем.
Какой бы подход вы ни выбрали, большинство ошибок носит систематический характер, это результат недопонимания между пользователем и программой. Понимание того, как пользователи думают, интерпретируют информацию, принимают решения и вводят данные, поможет вам отладить взаимодействие между вашей программой и вашими пользователями.
Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Giles Colborne
97 Вещей, Которые Должен Знать Каждый Программист
64. Предотвращайте Ошибки
Сообщения об ошибках - наиболее важные взаимодействия между пользователем и системой. Легко представить ошибку, вызванную неправильным вводом данных пользователем. Но люди систематически совершают вполне предсказуемые виды ошибок. Поэтому можно «отладить» связь между пользователем и системой так же, как и между компонентами системы.
Предположим, вы хотите, чтобы пользователь ввёл дату в допустимом диапазоне. Вместо того, чтобы позволять пользователю вводить любую дату, лучше предложить компонент UI вроде списка или календаря, предлагающего только разрешённые даты. Тогда ввести неверную дату будет невозможно.
Ошибки форматирования - ещё одна распространённая проблема. Например, пользователю предоставляется текстовое поле для ввода даты, и он вводит «
26.10.2020
». Неразумно отклонять её просто потому, что она имеет другой формат (например, вместо нужного «ДД/ММ/ГГГГ
»). Ещё хуже отклонить «26 / 10 / 2020
», потому что дата содержит лишние пробелы. Пользователю сложно будет понять, в чём ошибка, т.к. дата представлена в нужном формате.Такие ошибки возникают из-за того, что легче отклонить дату, чем проанализировать три или четыре наиболее распространённых формата даты и приводить их к нужному формату в программе. Подобные мелкие «недочёты» раздражают пользователя, что, в свою очередь, приводит к новым ошибкам, поскольку пользователь теряет концентрацию. Уважайте желание пользователей вводить информацию, а не данные.
Другой способ избежать ошибок форматирования - добавить подсказки. Например, с помощью метки в поле, показывающей желаемый формат («
ДД/ММ/ГГГГ
») или разделив поле на три цифровых по два, два и четыре символа.Есть два способа сообщить пользователю, как правильно ввести информацию: инструкции и подсказки. Подсказки кратки и отображаются в точке ввода информации, инструкции более подробны и обычно располагаются перед формой.
Как правило, инструкции не помогают предотвратить ошибку. Пользователи склонны предполагать, что интерфейс будет работать в соответствии с их прошлым опытом («Конечно, все знают, что означает «26.10.2020»). Так что инструкции остаются непрочитанными. Подсказки более полезны в предотвращении ошибок.
Другой способ избежать ошибок - предложить значения по умолчанию. Например, пользователи обычно вводят значения даты, соответствующие сегодняшнему дню, завтрашнему дню, их дню рождения, ранее введённой дате и т.п. В зависимости от контекста одно из этих значений, вероятно, будет хорошим выбором по умолчанию.
Какой бы ни была причина, системы должны снисходительно относиться к ошибкам пользователей. Помимо описанного выше, можно предоставить пользователю несколько уровней отмены действий, особенно тех, которые могут уничтожить или изменить данные пользователя.
Регистрация и анализ действий отмены также может выявить, где интерфейс провоцирует пользователей на ошибки, вроде постоянных нажатий «неправильной» кнопки. Эти ошибки часто возникают из-за вводящих в заблуждение подсказок или последовательности действий, которую можно изменить, чтобы предотвратить такие ошибки в дальнейшем.
Какой бы подход вы ни выбрали, большинство ошибок носит систематический характер, это результат недопонимания между пользователем и программой. Понимание того, как пользователи думают, интерпретируют информацию, принимают решения и вводят данные, поможет вам отладить взаимодействие между вашей программой и вашими пользователями.
Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Giles Colborne
👍1
День шестьсот тридцать шестой. #BestPractices #IDEALS
Принципы Разработки Микросервисов: IDEALS вместо SOLID. 1/7
В 2000 году Роберт Мартин составил пять принципов объектно-ориентированного проектирования, которые Майкл Фезерс позднее объединил в аббревиатуру SOLID. С тех пор принципы SOLID для объектно-ориентированного проектирования были неоднократно описаны в книгах и стали широко известны в отрасли.
Применимы ли принципы SOLID к микросервисам? Отчасти.
Мы, как отрасль, разрабатываем и внедряем решения на основе микросервисов уже более шести лет. За это время постоянно увеличивающееся количество инструментов, фреймворков, платформ и вспомогательных продуктов создали невероятно богатый технологический ландшафт вокруг микросервисов.
Такой ландшафт может вызвать головокружение у начинающих разработчиков микросервисов из-за множества дизайнерских и технологических решений, с которыми они могут столкнуться. И в этом случае базовый набор принципов может помочь разработчикам выбрать правильные проектные решения.
Хотя некоторые принципы SOLID применимы к микросервисам, объектная ориентация - это парадигма дизайна на уровне элементов (классов, интерфейсов, иерархий и т.д.), которые принципиально отличаются от элементов в распределённых системах в целом и микросервисах в частности.
Рассмотрим следующий набор основных принципов проектирования микросервисов:
I - Разделение интерфейсов
D - Легкость развёртывания
E – Ориентированность на события
A - Доступность важнее согласованности
L - Слабая связанность
S - Единственная ответственность
Эти принципы не охватывают весь спектр проектных решений для микросервисов, но они затрагивают ключевые проблемы и факторы успеха для создания современных систем на основе сервисов.
Продолжение следует…
Источник: https://www.infoq.com/articles/microservices-design-ideals/
Принципы Разработки Микросервисов: IDEALS вместо SOLID. 1/7
В 2000 году Роберт Мартин составил пять принципов объектно-ориентированного проектирования, которые Майкл Фезерс позднее объединил в аббревиатуру SOLID. С тех пор принципы SOLID для объектно-ориентированного проектирования были неоднократно описаны в книгах и стали широко известны в отрасли.
Применимы ли принципы SOLID к микросервисам? Отчасти.
Мы, как отрасль, разрабатываем и внедряем решения на основе микросервисов уже более шести лет. За это время постоянно увеличивающееся количество инструментов, фреймворков, платформ и вспомогательных продуктов создали невероятно богатый технологический ландшафт вокруг микросервисов.
Такой ландшафт может вызвать головокружение у начинающих разработчиков микросервисов из-за множества дизайнерских и технологических решений, с которыми они могут столкнуться. И в этом случае базовый набор принципов может помочь разработчикам выбрать правильные проектные решения.
Хотя некоторые принципы SOLID применимы к микросервисам, объектная ориентация - это парадигма дизайна на уровне элементов (классов, интерфейсов, иерархий и т.д.), которые принципиально отличаются от элементов в распределённых системах в целом и микросервисах в частности.
Рассмотрим следующий набор основных принципов проектирования микросервисов:
I - Разделение интерфейсов
D - Легкость развёртывания
E – Ориентированность на события
A - Доступность важнее согласованности
L - Слабая связанность
S - Единственная ответственность
Эти принципы не охватывают весь спектр проектных решений для микросервисов, но они затрагивают ключевые проблемы и факторы успеха для создания современных систем на основе сервисов.
Продолжение следует…
Источник: https://www.infoq.com/articles/microservices-design-ideals/
День шестьсот тридцать седьмой. #BestPractices #IDEALS
Принципы Разработки Микросервисов: IDEALS вместо SOLID. 2/7
I – Разделение Интерфейсов (Interface Segregation)
Исходный принцип разделения интерфейсов предостерегает от использования в ООП «жирных» интерфейсов. Другими словами, вместо интерфейса со всеми возможными методами, которые могут понадобиться клиентам, должны быть отдельные интерфейсы, обслуживающие конкретные потребности каждого типа клиентов.
Стиль микросервисной архитектуры - это специализация сервисно-ориентированной архитектуры (SOA), в которой дизайн интерфейсов (то есть контрактов сервисов) всегда имел первостепенное значение. С начала 2000-х, литература по SOA предписывала использовать канонические модели или канонические схемы, которым должны соответствовать все клиенты сервисов. Однако наш подход к разработке контрактов на обслуживание изменился со времен SOA. В эпоху микросервисов часто существует множество клиентских программ (фронтендов) для одной логики сервиса. Это основная мотивация применения принципа разделения интерфейсов к микросервисам.
Реализация разделения интерфейсов для микросервисов
Цель разделения интерфейсов для микросервисов состоит в том, чтобы каждый тип фронтенда получал контракт на обслуживание, который наилучшим образом соответствует его потребностям. Например: мобильное приложение хочет вызвать конечные точки, которые отвечают кратким представлением данных в формате JSON. Веб-приложение в той же системе использует полное представление объектов в JSON. Старое настольное приложение, которое вызывает ту же службу, требует полного представления, но в XML. Разные клиенты также могут использовать разные протоколы. Например, внешние клиенты могут использовать HTTP для вызова сервиса gRPC.
Вместо того, чтобы пытаться навязать один и тот же контракт (с использованием канонических моделей) для всех типов клиентов сервиса, мы «разделяем интерфейс», чтобы каждый тип клиента видел интерфейс сервиса, который ему нужен. Как это сделать? Отличным вариантом является использование шлюза API. Он может выполнять преобразование формата и структуры сообщений, преобразование протоколов, маршрутизацию сообщений и многое другое. Популярной альтернативой является шаблон Backend for Frontend (BFF). В этом случае у нас есть шлюз API для каждого типа клиента или разные BFF для каждого клиента, как показано на рисунке ниже.
Продолжение следует…
Источник: https://www.infoq.com/articles/microservices-design-ideals/
Принципы Разработки Микросервисов: IDEALS вместо SOLID. 2/7
I – Разделение Интерфейсов (Interface Segregation)
Исходный принцип разделения интерфейсов предостерегает от использования в ООП «жирных» интерфейсов. Другими словами, вместо интерфейса со всеми возможными методами, которые могут понадобиться клиентам, должны быть отдельные интерфейсы, обслуживающие конкретные потребности каждого типа клиентов.
Стиль микросервисной архитектуры - это специализация сервисно-ориентированной архитектуры (SOA), в которой дизайн интерфейсов (то есть контрактов сервисов) всегда имел первостепенное значение. С начала 2000-х, литература по SOA предписывала использовать канонические модели или канонические схемы, которым должны соответствовать все клиенты сервисов. Однако наш подход к разработке контрактов на обслуживание изменился со времен SOA. В эпоху микросервисов часто существует множество клиентских программ (фронтендов) для одной логики сервиса. Это основная мотивация применения принципа разделения интерфейсов к микросервисам.
Реализация разделения интерфейсов для микросервисов
Цель разделения интерфейсов для микросервисов состоит в том, чтобы каждый тип фронтенда получал контракт на обслуживание, который наилучшим образом соответствует его потребностям. Например: мобильное приложение хочет вызвать конечные точки, которые отвечают кратким представлением данных в формате JSON. Веб-приложение в той же системе использует полное представление объектов в JSON. Старое настольное приложение, которое вызывает ту же службу, требует полного представления, но в XML. Разные клиенты также могут использовать разные протоколы. Например, внешние клиенты могут использовать HTTP для вызова сервиса gRPC.
Вместо того, чтобы пытаться навязать один и тот же контракт (с использованием канонических моделей) для всех типов клиентов сервиса, мы «разделяем интерфейс», чтобы каждый тип клиента видел интерфейс сервиса, который ему нужен. Как это сделать? Отличным вариантом является использование шлюза API. Он может выполнять преобразование формата и структуры сообщений, преобразование протоколов, маршрутизацию сообщений и многое другое. Популярной альтернативой является шаблон Backend for Frontend (BFF). В этом случае у нас есть шлюз API для каждого типа клиента или разные BFF для каждого клиента, как показано на рисунке ниже.
Продолжение следует…
Источник: https://www.infoq.com/articles/microservices-design-ideals/