.net core vs framework. производительность коллекций

.NET Core release lifecycles

This table tracks release dates and end of support dates for .NET Core versions.

Version Original Release Date Latest Patch Version Patch Release Date Support Level End of Support
.NET Core 3.1 December 3, 2019 3.1.7 August 11, 2020 LTS December 3, 2022
.NET Core 3.0 September 23, 2019 3.0.3 February 18, 2020 EOL March 3, 2020
.NET Core 2.2 December 4, 2018 2.2.8 November 19, 2019 EOL December 23, 2019
.NET Core 2.1 May 30, 2018 2.1.21 August 11, 2020 LTS August 21, 2021
.NET Core 2.0 August 14, 2017 2.0.9 July 10, 2018 EOL October 1, 2018
.NET Core 1.1 November 16, 2016 1.1.13 May 14, 2019 EOL June 27 2019
.NET Core 1.0 June 27, 2016 1.0.16 May 14, 2019 EOL June 27 2019

Версии .NET Core

Выше я написал, что новый .NET Core имеет только один номер версии 2.0 preview 1, но это не совсем так. Есть два разных аспекта установки .NET Core: номер версии SDK/CLI (command line interface) и номер версии runtime (среды исполнения или .NET Core Shared Framework Host).

Если вы только-что установили 2.0 preview 1, то, если наберете в консоли dotnet —info, увидите примерно следующее:

Там целая куча разной информации, среди которой есть два разных номера версий:

  • 2.0.0-preview1-005977 — версия SDK
  • 2.0.0-preview1-002111-00 — версия среды исполнения

Но эти номера версий немного вводят в заблуждение. У меня на компьютере установлены также .NET Core SDK версии 1.0 и .NET Core Runtime версии 1.1.1 и 1.0.4, но здесь нет никакой информации о инх.

Runtime Configuration Files

Runtime Configuration Files.runtimeconfig.jsonSemVer.deps.json.deps.json

  • Секция
    Термином target называют целевую платформу (имя и версия), на котором должно выполняться данное приложение (напр., .NET Framework 4.6.2, .NET Core App 1.1, Xamarin.Mac 1.0, .NET Standard 1.6). Эта конфигурация аналогична NuGet target framework.
    Секция targets определяет платформу и дерево зависимостей для нее в формате
    Для выполнения любого приложения, target должен обязательно содержать RID, например .NETCoreApp,Version=v1.1/win10-x64. Файл deps.json Standalone-приложения всегда один и содержит RID целевой платформы. Для Portable-приложения файлов deps.json два — один в папке фреймворка, второй в папке приложения. RID для Portable-приложений указан в файле .deps.json в папке фреймворка. После того, как dotnet.exe определил фреймворк для выполнения приложения, он сперва загружает deps-файл этого фреймворка (например, C:\Program Files\dotnet\shared\Microsoft.NETCore.App\2.0.0\Microsoft.NETCore.App.deps), а затем deps-файл приложения. Deps-файл приложения имеет более высокий приоритет.
    Рассмотрим подробнее содержимое файла deps.json Standalone-приложения:
    В свойстве dependencies перечислены зависимости (пакеты) конкретного пакета.
    Свойство runtimeTargets используется в deps-файле Portable-приложения и определяет пути файлов библиотек для конкретного RID. Такие RID-specific библиотеки поставляются вместе с Portable-приложением в папке runtimes.
    Свойства runtime и native содержат относительные пути управляемых (managed) и нативных библиотек соответственно. Свойство resources содержит относительные пути и локали локализованных сборок-ресурсов.Пути относительны к NuGet package cache, а не deps-файлу.
    Добавить сторонний deps-файл можно передав значение аргумента —additional-deps или переменную среды DOTNET_ADDITIONAL_DEPS.Такая возможность доступна только для Portable приложений.
    Значение аргумента может содержать полный путь к deps-файлу, а также путь к директории, где расположены общие deps-файлы. Внутри этой директории deps-файлы должны быть расположены в структуре \shared\\\*.deps. Например, shared\Microsoft.NETCore.App\2.0.3\MyAdditional.deps.json.
    Когда dotnet.exe (MyApp.exe) определяет пути зависимостей приложения, для каждой отдельной библиотеки составляется список из runtime- и native-путей.
    Если в runtimeTargets для определенного RID есть библиотека, она добавляется к runtime- или native-списку исходя из указанного assetType.
  • Секция
    содержит название и версию целевой платформы для выполнения. Секция targets в действительности содержит два элемента — для компиляции (без RID) и выполнения (обязательно с RID). Секция runtimeTarget используется для удобства и дублирует значение из секции targets, чтобы dotnet.exe не тратил время на обработку targets секции. Как уже говорилось, для Standalone-приложения RID целевой ОС содержится в deps-файле приложения, а для Portable — в deps-файле фреймворка.
  • Секция
    определяет список всех зависимостей приложения (в формате ID пакета/версия:{metadata}) и содержит метаданные о каждой из них. В метаданных указываются:

    • тип зависимости (project, package, reference),
    • serviceable (только для типа package) — индикатор того, является ли пакет Serviceable (определяет, может ли сборка пакета быть пропатчена (заменена) внешними службами, Windows Update или ).
    • хэш пакета (для package зависимостей)
    • др. данные

.NET Core Runtimes (shared frameworks)

C:\Program Files\dotnetC:\Program Files\dotnet\shared

  • «Утилита» dotnet.exe для запуска .NET Core-приложения. Она называется мультплексор (muxer), и является основным драйвером инфраструктуры .NET Core. Эта программа служит «точкой входа» для запуска любых приложений и выполнения команд разработки. если установлена .NET Core SDK, то есть является хост-процессом любого приложения — corehost.
  • Runtime-компоненты (CoreCLR, CoreFX, и т.д.), устанавливаются в отдельную папку фреймворка C:\Program Files\dotnet\shared\\.
  • Host framework resolver — нативная библиотека, находится в папке
    C:\Program Files\dotnet\host\\hostfxr.dll. При запуске приложения, максимальная версия этой библиотеки выполняет разрешение версии фреймворка для последующего выполнения приложения.

MyApp.runtimeconfig.json

C:\Program Files\dotnet\shared\Microsoft.NETCore.App\2.0.0

Install Apache as reverse proxy

A reverse proxy is a common setup for serving dynamic web apps. The reverse proxy terminates the HTTP request and forwards it to the ASP.NET app.

Your application could technically run only with the Kestrel web server and without a reverse proxy. But if you want to install and manage your own SSL (https://) certifactes you should use a reverse proxy server (Nginx, Apache, IIS).

Update Ubuntu packages to their latest stable versions:

Install vim

Install the Apache web server on Ubuntu with a single command:

Enable the required apache modules:

Configure SSL

You only need to set up a virtual host for TLS/SSL. The following example assumes that an SSL certificate is located at and an associated key is located at .

Create and install an Apache self signed certificate:

Fill out the prompts appropriately. The most important line is the one that requests the Common Name (e.g. server FQDN or YOUR name). You need to enter the domain name associated with your server or, more likely, your server’s public IP address.

Output

More infos: How To Create a Self-Signed SSL Certificate for Apache in Ubuntu

Configure Apache

Add a server’s fully qualified domain name:

Add the following line to apache2.conf:

Configuration website files for Apache are located within the directory.
Any file with the extension is processed in alphabetical order.

Create a configuration file, named , for the app:

Copy and save this content to

See Name-based virtual host support for more information. Requests are proxied at the root to port of the server at .

For bi-directional communication, and are required.

To change Kestrel’s IP/port, see .

Save the file and test the configuration.

Disable the site:

Activate the site:

Test the configuration. If everything passes, the result should be .

Restart Apache:

Start your dotnet application:

If you open http://localhost/ you should be redirected to https://localhost/.

After you have accepted the self-signed certificate you should see the message.

Улучшения в Preview 1

Улучшение качества кода в RyuJIT

  • Улучшения для фолдинга null checks – Удалите необходимость генерировать null checks в большем количестве случаев, наблюдая больше шаблонов, где null checks, вероятно, не нужны.
  • Настройка общего подвыражения (CSE) – JIT ищет и сворачивает дублирующиеся выражения, которые нужно оценивать только один раз.
  • Оптимизация «constant_string».Length – Оптимизация этого шаблона и свертывание кода до правильного целочисленного значения.
  • JIT: создание базовых списков блоков перед морфингом – Переупорядочевание фазы в JIT, чтобы раньше можно было использовать ключевые оптимизации, что привело к лучшему качеству кода и меньшему количеству работы для следующих фаз, что увеличивает пропускную способность JIT («TP» в ссылочном PR).

Консолидация репозиториев GitHub

сократили количество репозиториев на GitHub

  • dotnet/runtime (были dotnet/corefx, dotnet/coreclr, и dotnet/core-setup)
  • dotnet/aspnetcore (было множество репозиториев в aspnet org)
  • dotnet/sdk (были dotnet/sdk, dotnet/cli)

Version History

Version Downloads Last updated

16.8.0-preview-20200812-03

5,697 8/13/2020

16.8.0-preview-20200806-02

2,416 8/6/2020

16.7.1

155,320 8/20/2020

16.7.0

369,988 8/6/2020

16.7.0-preview-20200519-01

51,982 5/20/2020

16.7.0-preview-20200428-01

32,517 4/28/2020

16.6.1

5,846,685 4/24/2020

16.6.0

364,449 4/20/2020

16.6.0-preview-20200318-01

65,598 3/20/2020

16.6.0-preview-20200310-03

14,771 3/13/2020

16.6.0-preview-20200309-01

11,590 3/9/2020

16.6.0-preview-20200226-03

36,105 2/27/2020

16.5.0

8,036,487 2/5/2020

16.5.0-preview-20200203-01

9,639 2/3/2020

16.5.0-preview-20200116-01

48,450 1/16/2020

16.5.0-preview-20200102-01

13,468 1/2/2020

16.5.0-preview-20191216-02

25,671 12/23/2019

16.5.0-preview-20191115-01

59,475 11/15/2019

16.4.0

8,482,847 11/6/2019

16.4.0-preview-20191007-01

5,269 10/7/2019

16.3.0

4,030,459 9/19/2019

16.3.0-preview-20190828-03

37,187 8/29/2019

16.3.0-preview-20190808-03

53,507 8/9/2019

16.3.0-preview-20190715-02

6,331 8/1/2019

16.2.0

13,585,595 6/27/2019

16.2.0-preview-20190606-02

30,553 6/7/2019

16.1.1

3,141,167 5/30/2019

16.1.0

2,587,464 5/9/2019

16.0.2-preview-20190502-01

11,220 5/2/2019

16.0.1

9,220,165 3/4/2019

16.0.0

270,028 2/28/2019

16.0.0-preview-20190203-03

50,685 2/3/2019

16.0.0-preview-20190201-03

3,565 2/1/2019

16.0.0-preview-20190124-02

82,646 1/25/2019

16.0.0-preview-20181205-02

221,532 12/5/2018

16.0.0-preview-20181128-01

1,616 11/28/2018

15.9.2

307,223 5/2/2019

15.9.1

56,167 3/6/2019

15.9.0

19,170,466 10/10/2018

15.9.0-preview-20180924-03

13,856 9/28/2018

15.9.0-preview-20180816-01

66,346 8/20/2018

15.9.0-preview-20180807-05

24,229 8/10/2018

15.8.0

10,356,361 7/13/2018

15.8.0-preview-20180610-02

94,521 6/11/2018

15.8.0-preview-20180605-02

14,924 6/5/2018

15.8.0-preview-20180510-03

43,900 5/10/2018

15.7.2

3,269,938 5/16/2018

15.7.0

5,045,929 4/4/2018

15.7.0-preview-20180320-02

30,187 3/22/2018

15.7.0-preview-20180307-01

9,805 3/8/2018

15.7.0-preview-20180221-13

41,567 2/21/2018

15.6.2

254,374 3/28/2018

15.6.1

881,058 3/9/2018

15.6.0

1,489,358 2/19/2018

15.6.0-preview-20180207-05

18,665 2/7/2018

15.6.0-preview-20180109-01

96,907 1/9/2018

15.6.0-preview-20171211-02

47,815 12/11/2017

15.5.0

5,662,803 11/9/2017

15.5.0-preview-20171031-01

34,169 10/31/2017

15.5.0-preview-20171025-02

7,701 10/26/2017

15.5.0-preview-20171012-09

30,755 10/13/2017

15.5.0-preview-20171009-10

10,755 10/10/2017

15.5.0-preview-20170923-02

35,286 9/26/2017

15.5.0-preview-20170914-09

50,846 9/14/2017

15.5.0-preview-20170810-02

205,647 8/10/2017

15.5.0-preview-20170727-01

17,247 7/28/2017

15.3.0

3,142,760 8/7/2017

15.3.0-preview-20170628-02

1,509,342 6/28/2017

15.3.0-preview-20170618-03

33,416 6/18/2017

15.3.0-preview-20170601-03

37,726 6/1/2017

15.3.0-preview-20170517-02

52,210 5/18/2017

15.3.0-preview-20170502-03

34,625 5/3/2017

15.3.0-preview-20170427-09

80,873 4/27/2017

15.3.0-preview-20170425-07

73,068 4/25/2017

15.0.0

9,244,495 2/23/2017

15.0.0-preview-20170222-09

8,366 2/22/2017

15.0.0-preview-20170217-05

8,746 2/17/2017

15.0.0-preview-20170210-02

12,657 2/10/2017

15.0.0-preview-20170125-04

32,636 1/27/2017

15.0.0-preview-20170123-02

33,491 1/23/2017

15.0.0-preview-20170113-02

2,109 1/13/2017

15.0.0-preview-20170106-08

586,724 1/6/2017

15.0.0-preview-20161227-02

8,042 12/27/2016

15.0.0-preview-20161216-01

2,330 12/16/2016

15.0.0-preview-20161123-03

34,955 11/24/2016

15.0.0-preview-20161122-02

880 11/22/2016

IoC, DI, DIP

Если театр начинается с вешалки, то ASP.NET Core начинается с Dependency Injection. Для того, чтобы разобраться с DI нужно понять, что такое IoC.

Говоря о IoC очень часто вспоминают голливудский принцип «Don’t call us, we’ll call you». Что означает «Не нужно звонить нам мы позвоним вам сами».

Различные источники приводят различные паттерны, к которым может быть применен IoC. И скорее всего они все правы и просто дополняют друг друга. Вот некоторые их этих паттернов: factory, service locator, template method, observer, strategy.

Давайте разберем IoC на примере простого консольного приложения.

Допустим у нас есть два простых класса, реализующих интерфейс с одним методом:

Они оба зависят от абстракции (в данном случае в виде абстракции выступает интерфейс).

И, допустим, у нас есть объект более высокого уровня, использующий эти классы:

В зависимости от параметра конструктора переменная _instance инициализируется определенным классом. Ну и далее при вызове Write будет совершен вывод на консоль или в Debug. Все вроде бы неплохо и даже, казалось бы, соответствует первой части принципа Dependency Inversion

В качестве абстракции в нашем случае выступает ILayer.

Но у нас должен быть еще и объект еще более высокого уровня. Тот, который использует класс Logging

Инициализируя Logging с помощью 1 мы получаем в классе Logging экземпляр класса, выводящего данные на консоль. Если мы инициализируем Logging любым другим числом, то log.Write будет выводить данные в Debug. Все, казалось бы, работает, но работает плохо. Наш объект более высокого уровня Main зависит от деталей кода объекта более низкого уровня – класса Logging. Если мы в этом классе что-то изменим, то нам необходимо будет изменять и код класса Main. Чтобы это не происходило мы сделаем инверсию контроля – Inversion of Control. Сделаем так чтобы класс Main контролировал то, что происходит в классе Logging. Класс Logging будет получать в виде параметра конструктора экземпляр класса, реализующего интерфейс интерфейс ILayer

И теперь нас класс Main будет выглядеть таким образом:

Фактически мы декорируем наш объект Logging с помощью необходимого для нас объекта.

Теперь наше приложение соответствует и второй части принципа Dependency Inversion:

Есть такой термин tight coupling – тесная связь. Чем слабее связи между компонентами в приложении, тем лучше. Хотелось бы заметить, что данный пример простого приложения немного не дотягивает до идеала. Почему? Да потому что в классе самого высокого уровня в Main у нас дважды используется создание экземпляров класса с помощью new. А есть такая мнемоническая фраза «New is a clue» — что означает чем меньше вы используется new, тем меньше тесных связей компонентов в приложении и тем лучше. В идеале мы не должны были использовать new DebugLayer, а должны были получить DebugLayer каким-нибудь другим способом. Каким? Например, из IoC контейнера или с помощью рефлексии из параметра передаваемого Main.

Теперь мы разобрались с тем, что такое Inversion of Control (IoC) и что такое принцип Dependency Inversion (DIP). Осталось разобраться с тем, что такое Dependency Injection (DI). IoC представляет собой парадигму дизайна. Dependency Injection это паттерн. Это то, что у нас теперь происходит в конструкторе класса Logging. Мы получаем экземпляр определенной зависимости (dependency). Класс Logging зависит от экземпляра класса, реализующего ILayer. И это экземпляр внедряется (injected) через конструктор.

REST-сервисы на ASP.NET Core под Linux в продакшене +42

  • 02.04.18 11:55


e_finkel

#352168

Хабрахабр

7300

.NET, Высокая производительность, Разработка под Linux, Работа с видео, Блог компании Конференции Олега Бунина (Онтико)

В основе этой статьи доклад Дениса Иванова (@DenisIvanov) на РИТ++ 2017, в котором он поделился опытом разработки и запуска в продакшен REST-сервиса на ASP.NET Core на Kubernetes. На текущий момент это сделать уже можно без особенных проблем и бояться использовать .NET Core, судя по опыту 2ГИС, не стоит.
Конфигурация: ASP.NetCore на Linux позволила не только использовать существующую on-premise платформу, но и принесла еще несколько дополнительных плюсов, в частности, в виде полноценных Docker и Kubernetes, которые сильно упрощают жизнь.

.NET Core

.NET Core is a cross-platform version of .NET for building websites, services, and console apps.

Version Status Visual Studio 2017 SDK Visual Studio 2019 SDK Runtime Release notes
.NET 5.0

Preview

N/A x64 SDK
|
x86 SDK
(v5.0.100-preview.8)
x64 Runtime
|
x86 Runtime
(v5.0.0-preview.8)
Release notes
.NET Core 3.1

LTS

N/A x64 SDK
|
x86 SDK
(v3.1.401)
x64 Runtime
|
x86 Runtime
(v3.1.7)
Release notes
.NET Core 3.0

End of life

N/A x64 SDK
|
x86 SDK
(v3.0.103)
x64 Runtime
|
x86 Runtime
(v3.0.3)
Release notes
.NET Core 2.2

End of life

x64 SDK
|
x86 SDK
(v2.2.110)
x64 SDK
|
x86 SDK
(v2.2.207)
x64 Runtime
|
x86 Runtime
(v2.2.8)
Release notes
.NET Core 2.1

LTS

x64 SDK
|
x86 SDK
(v2.1.517)
x64 SDK
|
x86 SDK
(v2.1.809)
x64 Runtime
|
x86 Runtime
(v2.1.21)
Release notes
.NET Core 2.0

End of life

x64 SDK
|
x86 SDK
(v2.1.202)
x64 SDK
|
x86 SDK
(v2.1.202)
x64 Runtime
|
x86 Runtime
(v2.0.9)
Release notes
.NET Core 1.1

End of life

x64 SDK
|
x86 SDK
(v1.1.14)
x64 SDK
|
x86 SDK
(v1.1.14)
x64 Runtime
|
x86 Runtime
(v1.1.13)
Release notes
.NET Core 1.0

End of life

x64 SDK
|
x86 SDK
(v1.1.14)
x64 SDK
|
x86 SDK
(v1.1.14)
x64 Runtime
|
x86 Runtime
(v1.0.16)
Release notes

AOP с помощью ASP.NET Core — Autofac Interseptors

Говоря про аспектно-ориентированное программирование, упоминают другой термин – cross-cutting concerns. Concern – это какая-то часть информации, которая влияет на код. В русском варианте употребляют слово ответственность. Ну а cross-cutting concerns это ответственности, которые влияют на другие ответственности. А в идеале ведь они не должны влиять друг на друга, так ведь? Когда они влияют на друг друга, то становится сложнее изменять программу. Удобнее, когда у нас все операции происходят по отдельности. Логирование, транзакции, кеширование и многое другое можно совершать с помощью AOP не изменяя код самих классов и методов.

В мире .NET часто применяется способ, когда AOP код внедряется с помощью пост-процессора в уже откомпилированный код приложения (PostSharp) Или же альтернативно можно применять интерцепторы – это такие перехватчики событий, которые можно добавлять в код приложения. Эти перехватчики, как правило, используют для своей работы уже рассмотренный нами паттерн декоратор.

Давайте создадим свой интерцептор. Самый простой и типичный пример, который проще всего воспроизвести — это логирование.
Установим дополнительно к пакету Autofac.Extensions.DependencyInjection еще и пакет Autofac.Extras.DynamicProxy
Установили? Добавим простенький класс лога, который будет вызываться при обращении к определенным сервисам.

Добавляем в нашу регистрацию Autofac регистрацию интерцептора:

И теперь при каждом обращении к классу будет вызван метод Intercept класса Logger.
Таким образом мы можем упростить себе жизнь и не писать в начале каждого метода запись в лог. Она у нас будет вестись автоматически. И при желании нам будет несложно ее изменить или отключить для всего приложения.

Также мы можем убрать .InterceptedBy(typeof(Logger)); и добавить перехват вызовов только для конкретных сервисов приложения с помощью атрибута – необходимо указать его перед заголовком класса.

Create a new ASP.NET Core web application

Let’s create our first ASP.NET Core “hello world” web app. Just run:

The command should start the webserver on a new open port (5001 for https and 5000 for http).

Expected output:

Now open your browser with the url you can see in the console output:

  • For example: http://localhost:5000 or https://localhost:5001
  • You should see a message like:

Change the listening address via command line

The following command allows access to the kestrel webserver from anywhere.
This parameter is usful to access the website from another host via docker or VirtualBox.

Please also check the current firewall status with

Microsoft.Extensions.Logging

If you want only the logging integration:

dotnet add package Sentry.Extensions.Logging

See the logging integration only sample

Internals/Testability

It’s often the case we don’t want to couple our code with static class like , especially to allow our code to be testable.
If that’s your case, you can use 2 abstractions:

  • ISentryClient
  • IHub

The is responsible to queueing the event to be sent to Sentry and abstracting away the internal transport.
The on the other hand, holds a client and the current scope. It in fact also implements and is able to dispatch calls to the right client depending on the current scope.

In order to allow different events hold different contextual data, you need to know in which scope you are in.
That’s the job of the . It holds the scope management as well as a client.

If all you are doing is sending events, without modification/access to the current scope, then you depend on . If on the other hand you would like to have access to the current scope by configuring it or binding a different client to it, etc. You’d depend on .

An example using for testability is SentryLogger and its unit tests SentryLoggerTests. depends on because it does modify the scope (through ). In case it only sent events, it should instead depend on

Топ-цели .NET 5

  • Унифицированный опыт .NET SDK:
    • Один BCL (библиотека базовых классов) для всех приложений .NET 5. Сегодня приложения Xamarin используют Mono BCL, но перейдут на использование .NET Core BCL, улучшая совместимость между нашими моделями приложений.
    • Мобильная разработка (Xamarin) интегрирована в .NET 5. Это означает, что .NET SDK будет поддерживать mobile. Например, вы можете использовать «dotnet new XamarinForms» для создания мобильного приложения.
  • Нативные приложения, поддерживающие несколько платформ: проект «Одно устройство», который поддерживает приложение, которое может работать на нескольких устройствах, например Window Desktop, Microsoft Duo (Android) и iOS, с использованием собственных элементов управления, поддерживаемых на этих платформах.
  • Веб-приложения, поддерживающие несколько платформ: один проект Blazor, который поддерживает приложение, которое может работать в браузерах, на мобильных устройствах и как собственное настольное приложение (например, Windows 10x).
  • Собственные облачные приложения: высокопроизводительные микросервисы с одним файлом (.exe) <50 МБ и поддержка создания нескольких проектов (API, веб-интерфейсов, контейнеров) как локально, так и в облаке.
  • Непрерывные улучшения, такие как: ускорение алгоритмов в BCL, улучшения поддержки контейнеров во время выполнения, поддержка HTTP3.

ASP.NET Core integration

To use Sentry with your ASP.NET Core project, simply install the NuGet package:

dotnet add package Sentry.AspNetCore

Change your by adding :

public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        // Integration
        .UseSentry()
        .Build();

Logging integration

This will also automatically include the integration to . That means that any or by default will send an event to Sentry.

Log messages of level will be kept as breadcrumbs and if an event is sent, all breadcrumbs from that transaction are included.

These levels can be configured so that the level you define tracks breadcrumbs or sends events or completely disable it.

That means that log messages logged by you or the framework, related to the failed transaction, will be added to the event!

Собираем libsoplugin с lldb-4.0

К счастью, нам понадобится только плагин. Не придётся использовать кастомный .NET Core и т.д. Плагин будем использовать прямо из папки, в которой мы его соберём, так что система не замусорится.

Собственно, в репозитории CoreCLR есть инструкции по сборке под Linux. Мы только немного подправим их, чтобы воспользоваться lldb-4.0.

Я использую Ubuntu 16.04. Для других дистрибутивов набор команд может несколько отличаться.

  1. Ставим необходимые инструменты для сборки:

  2. Клонируем репозиторий:

  3. Применяем следующий патч:

  4. Собираем CoreCLR:

Ура, мы получили работающий плагин для lldb-4.0.

Удаление элементов управления Windows Forms

  • DataGrid
  • ToolBar
  • ContextMenu
  • Menu
  • MainMenu
  • MenuItem
Старый элемент (API) Рекомендуемая замена Другие связанные удаленные API
DataGrid DataGridView DataGridCell, DataGridRow, DataGridTableCollection, DataGridColumnCollection, DataGridTableStyle, DataGridColumnStyle, DataGridLineStyle, DataGridParentRowsLabel, DataGridParentRowsLabelStyle, DataGridBoolColumn, DataGridTextBox, GridColumnStylesCollection, GridTableStylesCollection, HitTestType
ToolBar ToolStrip ToolBarAppearance
ToolBarButton ToolStripButton ToolBarButtonClickEventArgs, ToolBarButtonClickEventHandler, ToolBarButtonStyle, ToolBarTextAlign
ContextMenu ContextMenuStrip
Menu ToolStripDropDown, ToolstripDropDownMenu MenuItemCollection
MainMenu MenuStrip
MenuItem ToolstripMenuItem

List

Цикл for

Method Runtime Size Mean Error StdDev Ratio
IterateFor_Int .NET 4.8 1000 565.09 ns 0.191 ns 0.127 ns 1.00
IterateFor_Int .NET Core 2.1 1000 451.14 ns 0.236 ns 0.156 ns 0.80
IterateFor_Int .NET Core 3.1 1000 451.08 ns 0.143 ns 0.085 ns 0.80
IterateFor_String .NET 4.8 1000 574.80 ns 6.795 ns 4.494 ns 1.00
IterateFor_String .NET Core 2.1 1000 460.86 ns 3.771 ns 2.494 ns 0.80
IterateFor_String .NET Core 3.1 1000 460.35 ns 0.681 ns 0.405 ns 0.80

В Core JIT генерирует более эффективный код, чтение элементов из List в цикле for стало быстрее на ~20%.

Цикл foreach

Method Runtime Size Mean Error StdDev Ratio
IterateForEach_Int .NET 4.8 1000 1,574.5 ns 2.73 ns 1.81 ns 1.00
IterateForEach_Int .NET Core 2.1 1000 1,575.8 ns 3.82 ns 2.27 ns 1.00
IterateForEach_Int .NET Core 3.1 1000 1,568.1 ns 0.61 ns 0.40 ns 1.00
IterateForEach_String .NET 4.8 1000 8,046.3 ns 36.51 ns 24.15 ns 1.00
IterateForEach_String .NET Core 2.1 1000 6,465.0 ns 15.26 ns 10.09 ns 0.80
IterateForEach_String .NET Core 3.1 1000 5,886.3 ns 14.65 ns 9.69 ns 0.73

Итерирование List с ссылочными типами через foreach стало быстрее на 27%, но для значимых типов ничего не поменялось. Здесь можно оценить, насколько foreach медленнее, чем for. Разница в их эффективности на Core составляет 3.5x (value types) и 12x (reference types), примерно также как и в полном фреймворке.

Add

Чтобы протестировать метод без ресайза внутреннего массива в тесте используется конструктор List с заданной ёмкостью (capacity).

Method Runtime Size Mean Error StdDev Ratio
Add_Int .NET 4.8 1000 2,006.5 ns 11.65 ns 6.93 ns 1.00
Add_Int .NET Core 2.1 1000 1,249.0 ns 1.00 ns 0.60 ns 0.62
Add_Int .NET Core 3.1 1000 1,260.9 ns 5.88 ns 3.89 ns 0.63
Add_String .NET 4.8 1000 3,250.8 ns 53.13 ns 35.14 ns 1.00
Add_String .NET Core 2.1 1000 2,816.8 ns 37.26 ns 22.18 ns 0.87
Add_String .NET Core 3.1 1000 2,538.2 ns 30.55 ns 20.21 ns 0.78

На Core 3 добавление работает быстрее на 22% (reference types) и 37% (value types). Что изменилось в коде метода? Добавление без ресайза, т.е. самый частый вариант выделен в отдельный метод с атрибутом , т.е. он теперь инлайнится. Из мелких оптимизаций: убраны две лишние проверки выхода за границы и значение поля теперь кешируется в локальную переменную.

Contains

Давайте возьмём негативный сценарий для метода Contains: будем искать элементы, которых нет в коллекции.

Method Runtime Size Mean Error StdDev Ratio
Contains_Int .NET 4.8 1000 1,128.975 us 5.4951 us 3.6347 us 1.00
Contains_Int .NET Core 2.1 1000 456.040 us 0.1437 us 0.0950 us 0.40
Contains_Int .NET Core 3.1 1000 188.002 us 0.1619 us 0.0964 us 0.17
Contains_String .NET 4.8 1000 4,027.20 us 9.479 us 5.641 us 1.00
Contains_String .NET Core 2.1 1000 3,332.93 us 2.156 us 1.128 us 0.83
Contains_String .NET Core 3.1 1000 2,723.48 us 2.460 us 1.464 us 0.68

На Core 3 поиск Int в List стал примерно в 6 раз быстрее, а поиск строк — в 1.4 раза. В Core JIT научился в некоторых ситуациях девирутализировать виртуальные методы, т.е. они вызываются напрямую. Более того, такие методы могут быть заинлайнены. В данном случае девиртуализируется метод , который используется для сравнения элементов. В случае с Int всё сводится к вызову , который к тому же инлайнится. В итоге получившийся код по эффективности близок к прямому сравнению двух Int.

Кстати, раньше я всегда думал, что метод Contains внутри вызывает IndexOf, но оказалось, что это верно только для Core. В полном фреймворке это разные методы, и работают они с разной скоростью.

List Methods Summary

Сводная таблица относительной производительности (ratio) основных методов List при N = 1000.

List Method Type .NET 4.8 Core 2.1 Core 3.1 Details
Ctor Int 1.00 0.82 0.47 Report
Ctor String 1.00 0.90 0.92 Report
IterateFor Int 1.00 0.80 0.80 Report
IterateFor String 1.00 0.80 0.80 Report
IterateForEach Int 1.00 1.00 1.00 Report
IterateForEach String 1.00 0.80 0.73 Report
Add Int 1.00 0.62 0.63 Report
Add String 1.00 0.87 0.78 Report
Contains Int 1.00 0.40 0.17 Report
Contains String 1.00 0.83 0.68 Report
IndexOf Int 1.00 0.99 0.43 Report
IndexOf String 1.00 0.95 0.95 Report

Array Methods Summary

Подробно останавливаться на методах массива я не буду, поскольку List — это обертка над массивом.
Так что здесь я приведу таблицу относительной производительности Array при N = 1000.

Array Method Type .NET 4.8 Core 2.1 Core 3.1 Details
Ctor Int 1.00 0.73 0.88 Report
Ctor String 1.00 0.75 0.84 Report
IterateFor Int 1.00 0.86 1.00 Report
IterateFor String 1.00 1.00 1.00 Report
IterateForEach Int 1.00 0.84 1.00 Report
IterateForEach String 1.00 1.00 1.00 Report

Здесь можно отметить, что как и прежде, цикл foreach для массива преобразуется в обычный for. Т.е. с точки зрения производительности для итерации массива нет разницы какой из циклов использовать.

And configuring Kestrel for a web environment

Gustavo Hernan SicilianoFollow

Jul 26, 2017 · 3 min read

This post is the first of a series in which we’ll discuss about the experience of developing and running .NET web applications in Linux environments.

Introduction to .NET Core

.NET Core is an opensource, multiplatform version the .NET Framework which is officially supported and maintained by Microsoft.

This post will give an overview of how to run a .NET Core web project in Ubuntu, starting with its basic architecture and ending in the configuration of Kestrel for creating a web application.

.NET Core framework already provides scaffolding tools for bootstrapping your projects, but this time we’ll develop this from scratch starting from a basic console application.

Installing .NET Core on Linux

We’ll install .NET Core in Ubuntu, following Microsoft’s , but you can find installation instructions for most common distros. As a development IDE you can use any text editor, but we are going to use Visual Studio Code which, in my opinion, offers the best integration.

Creating my first “Hello world” in C # .NET Core

From the command console run these commands:

  • (to create a console project in .NET Core)
  • (to restore packages and project dependencies)
  • (to execute our code).

Configuring Kestrel

Kestrel is a multi-platform web server used to host .NET Core web applications.

To add Kestrel to our project we must add the it’s dependencies to the file as follows:

Now we will open our Program.cs file and in it’s method replace the following lines:

For these lines:

In order to use Kestrel and the HTTP context we will have to add these references:

Now we need to add the .

Using Startup.cs

With the file we are going to configure for the project host.

By now our should be looking something like this:

The method is called at runtime and it is used to configure and channel HTTP requests.

provides the mechanisms for configuring application requests. The middleware is also configured here.

Next, we will configure the app to use IIS/IIS Express for the web server and set the content root. To do this we will add the following lines before the in :

To use IIS with ASP.NET Core, both and must be specified. Kestrel is designed to run behind a proxy and should not be deployed without it.

Now let’s add the IIS package reference in , and run for updating dependencies.

We will add “Watcher” to see the changes reflected without needing to stop and re-run the project. For that we are going to add the following dependency:

As always we will have to run , and now if we run we should be able to see our changes being reflected without us having to reload out application.

Congratulations!

You already have your .Net Core application running on Linux and you learned how to configure it from scratch using Kestrel and develop it in a web environment. In the next post, I explain how to build an MVC architecture application using the tools provided by .Net Core.

Шаг 1 – Запустите Portability Analyzer

.NET Portability Analyzer

  • На первой вкладке, Portability Summary, если в столбце .NET Core все значения стоят на 100% (все выделено зеленым), ваш код полностью совместим, и вы можете перейти к Шагу 2.
  • Если у вас есть значения менее 100%, сначала посмотрите на все сборки, которые не являются частью вашего приложения. Для них нужно проверить, предоставляют ли их авторы версии для .NET Core или .NET Standard.
  • Теперь посмотрите на другую часть сборок, которая поступает из вашего кода. Если в Portability Report не указано ни одной сборки, перейдите к Шагу 2. Как только вы это сделаете, откройте вкладку Details, отфильтруйте таблицу, кликнув столбец Assembly и сосредоточьтесь только на тех, которые связаны с вашим приложением. Просмотрите список и рефакторинг кода, чтобы прекратить использование API или заменить использование API с альтернативами .NET Core.

Установка .NET Core 2.0 Preview 1 SDK

Очевидно, первое, что нужно сделать — установить .NET Core 2.0 Preview 1 SDK отсюда. Это очень легко: никакого выбора вариантов установки — просто скачиваете и устанавливаете. И там только один номер версии!

Одно небольшое замечание: .NET Core теперь также включает ASP.NET Core. Это значит, что вам нужно устанавливать меньше внешних пакетов, когда вы разворачиваете свое приложение, что не может не радовать!

Стоит также отметить, что, если вы хотите создавать приложения ASP.NET Core 2.0 в Visual Studio, вам нужно будет установить предварительную версию Visual Studio 2017. Её можно устанавливать параллельно со стабильной версией.

Применяем теорию на практике

  1. Открываем наш снапшот в lldb:

  2. Загружаем собранный плагин:

  3. Дампим статистику по использованию кучи:

    Первая колонка — это адрес method table для объектов данного класса, вторая — количество аллоцированных объектов данного класса, третья — количество аллоцированных байт, четрвёртая — имя класса.

    По выводу не сложно догадаться, кто же течёт.

  4. Получаем стек, в котором создан объект (команды могут выполняться ооочень долго):

    Получаем огромную таблицу в которой первая колонка — адрес инстанса этого класса, вторая — адрес method table, третья — размер инстанса в байтах.

    Выбираем какой-нибудь инстанс и выполняем команду:

    И как видим, нам указывают как раз на строку

    в исходном файле.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *