PDSW

Pragmatical Development and some Workarounds

Улучшаем производительность в .NET Core (по опыту бинарного сериализатора Hagar)

От переводчика: рекомендую к Вашему внимаию перевод статьи Reuben Bond-а Performance Tuning for .NET Core . Тут, пожалуй, описаны почти все последние инструменты dotnet, которые помогут вашим приложениям достичь новых высот производительности. Статья интересна ещё и ссылками, которые просто must read!

Кто-то из вас, возможно, знает, что я трачу все свое время на то, чтобы завершить разработку новой .NET библиотеки сериализации. Сериализатор, должен вам сказать, оказался очень сложным в реализации. Он должен быть надежным, гибким и быстрым, безупречным в работе. Я не буду убеждать вас, что библиотеки сериализации должны быть быстрыми - в этом посте это само собой разумеется. Вот несколько советов из моего опыта по оптимизации производительности Hagar. Большая часть этих советов применима к другим типам библиотек или приложений.

Читать дальше...


Реализация паттерна предохранитель на C#

предохранитель

Что такое паттерн предохранитель?

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

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

Читать дальше...


Почему выражения с динамическими типами данных медленнее чем со статическими в C#?

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

Читать дальше...


Асинхронное ожидание внутри lock-а C#

Вы когда-нибудь пытались ожидать завершение выполнения задачи внутри блока lock на C#? Если Вам приходила в голову такая идея но никак не доходили руки до воплощения, то предлагаю не спешить. Во-первых компилятор не даст это сделать, а во-вторых у разработчиков dotnet есть другие возможности решать проблему блокировки раделяемых ресурсов в асинхронном коде. Предлагаю с ними ознакомится под катом.

Читать дальше...


Автомок при помощи AutoFixture

Исходя из того что теперь вы знаете что такое авто-мок, хочу Вас обрадовать ещё одной штукой: AutoFixture - библиотекой разработанной Mark Seemann-ом которая предоставляет функционал автомока. О том как им воспользоваться и будет этот перевод статьи с блога автора.

Читать дальше...


Деревья принятия решений на C#

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

дерево принятия решений

Предисловие переводчика: если Вам хочется попробовать немного Machine Learning и не хочется выходить за пределы родного dotnet - Вы можете воспользоваться фреймворком Accord Net. Статья за авторством César Souza создателя вышеупомянутого фреймворка поможет сделать первые шаги в этом направлении и в качестве примера решить небольшую задачку при помощи алгоритма деревьев принятия решений.

Ещё хотел бы добавить замечательный перевод Андрея Будая проясняющий работу алгоритмов ID3 и C4.5 и математику стоящую за ними

Читать дальше...


Авто-мок контейнер от Mark Seemann

Как можно отделить юнит тесты от механизма Dependency Injection? В этой статье описывается паттерн юнит тестов (unit test), называемый автомок (Auto-mocking Container). Его можно использовать для устранения проблемы хрупких тестов (Fragile Test), которые так часто происходят при создании тестируемой системы (system under tests - SUT) при помощи антипаттерна Мать объекта. На этот вопрос отвечает Mark Seemann.

Читать дальше...


Правило молчания и уровни логирования

философия unix

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

Нет единой, стандартизированной формулировки философии Unix, но, возможно, самое простое описание было бы: “Пишите такие программы, которые будут небольшими, простыми и очевидными. Пишите их так, чтобы они делали только одно, но делали это хорошо и могли работать совместно с другими программами”. То есть, философия сосредотачивается вокруг концепта понятий малости, простоты, модульности, мастерства, прозрачности, экономии, разнообразия, переносимости, гибкости и расширяемости.

Эта философия стала основой того, что Unix-подобные операционные системы стали основными в течение более трех десятилетий, гораздо дольше, чем любые другие семейства операционных систем, и скорее всего, мы увидим их дальнейшее расширение использования в последующих годах, в частности, в форме Linux.

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

Читать дальше...


Что такое sync over async deadlock

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

Вспомним пример из предудущего поста. По нажатию на кнопку нужно вызвать длительную задачу. Так как наш код асинхронный, код длительной задачи нужно разместить в синхронном коде обработчика нажатия кнопки, для этого воспользуемся техникой sync over async. Т.е. просто дождёмся завершения асинхронной задачи при помощи метода taskName.Wait().

multithreading

Читать дальше...


Контекст синхронизации при работе с Task и Thread

При работе в проектах связанными с ui-control или asp.net часто приходится работать с ресурсами доступными в локальном хранилище потока (thread-local storage TLS). К слову: такое поведение можно задать при помощи аттрибута [ThreadStatic] или класса ThreadLocal<T>. При обращении к ним из другого потока платформа dotnet выбросит исключение System.InvalidOperationException с текстом ‘The calling thread cannot access this object because a different thread owns it.’.

Представим себе ситуацию когда в каком-то win-form приложении нам по нажатию кнопки нужно вызвать долгоиграющую задачу. Очевидно, что нужно было-бы создать поток и в этом потоке выполнить эту задачу. Проблематично будет отобразить результат выполнения из созданного потока на UI - ведь ресурсы UI принадлежат одному потоку, а обращаемся мы к нему в другом. Это и есть та вышеописанная ситуация, когда мы столкнёмся с System.InvalidOperationException. Для решения этой проблемы нам придётся подружиться с контекстом синхронизации. multithreading

Читать дальше...