Posted on 10. May 2019

Улучшенная диагностика в .NET Core 3.0

В .NET Core 3.0 добавлен набор инструментов, которые используют новые функции в .NET среде, что значительно улучшает диагностику и производительность.

Эти функции помогут Вам ответить на некоторые распространенные вопросы диагностики:

  1. Все ли в порядке с моим приложением?
  2. Почему возникает аномальное поведение в моем приложении?
  3. Почему мое приложение падает?

Все ли в порядке с моим приложением?

Часто приложения могут запускать утечку памяти и в конечном итоге это приводит к нехватки памяти. В других случаях определенные проблемные пути кода могут привести к скачку использования ЦПУ. Это лишь некоторые из проблем, которые Вы можете активно идентифицировать с помощью метрик.

Метрики

Метрики - это данные измерений за определенные промежутки времени. Данные метрик (или временных рядов) позволят Вам наблюдать за состоянием Вашей системы самым лучшим образом. В отличие от .NET Framework на  Windows, .NET Core не отслеживает производительность. Поэтому был добавлен новый способ генерирования метрик в .NET Core с помощью EventCounter API.

EventCounters намного лучше по сравнению с Windows счетчиками производительности, поскольку теперь они используются на всех ОС, где поддерживается .NET Core. Кроме того, в отличие от счетчиков производительности, они также могут использоваться в средах с низким уровнем привилегий (например, при xcopy развертывании). К сожалению, отсутствие такого инструмента, как Performance Monitor (perfmon), затрудняет использование этих метрик в режиме реального времени.

dotnet-counters

В .NET Core 3.0 Preview 5 есть новый инструмент командной строки для наблюдения за метриками, генерируемыми .NET Core Applications в режиме реального времени.

Вы можете установить этот .NET инструмент, выполнив следующую команду.

dotnet tool install --global dotnet-counters --version 1.0.3-preview5.19251.2

 

Для получения подробных инструкций о том, как использовать этот инструмент, перейдите на dotnet-counters readme. Для ознакомления с известными ограничениями dotnet-counters, перейдите на GitHub.

Почему возникает аномальное поведение в моем приложении?

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

Трассировка

Трассировки - это неизменные записи дискретных событий с отметкой времени. Трассировки содержат локальный контекст, который позволяет лучше определить сбой системы. Обычно .NET Framework (и такие фреймворки, как ASP.NET) генерировали диагностические трассировки о своих внутренних компонентах с помощью Event Tracing для Windows (ETW). В .NET Core эти трассировки были прописаны в ETW для Windows и LTTng для Linux.

dotnet-trace

В .NET Core 3.0 Preview 5 каждое .NET Core приложение открывает двойной канал с именем EventPipe (Unix сокет домен именованный pipe на Windows), через который можно отправлять события. На данный момент ведутся работы над протоколом контроллера, dotnet-trace реализует preview-версию этого протокола.

Вы можете установить этот .NET инструмент, выполнив следующую команду

dotnet tool install --global dotnet-trace--version 1.0.3-preview5.19251.2

 

В приведенном выше примере запускается dotnet trace с профилем по умолчанию, который включает аналитику событий ЦПУ и события .NET среды. 

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

В результате запуска dotnet trace Вы получаете .netperf файл. Этот файл содержит события времени выполнения и выборки ЦПУ стеков, которые можно визуализировать в perfview. Следующее обновление Visual Studio (16.1) также добавит поддержку для визуализации этих трассировок.

Если при записи трассировки Вы работаете на X или Linux, Вы можете преобразовать эти .netperf файлы в .speedscope.json файлы, которые можно визуализировать с помощью Speedscope.app.

Вы можете преобразовать уже существующую трассировку, выполнив следующую команду

dotnet trace convert <input-netperf-file>

Изображение ниже показывает диаграмму, визуализирующую трассировку, которую Вы только что зафиксировали в Speedscope.

Для получения подробных инструкций о том, как использовать этот инструмент, перейдите на dotnet-trace readme. Для ознакомления с известными ограничениями dotnet-trace, перейдите на GitHub.

Почему мое приложение падает?

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

Dump анализ

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

Обычно Вы полагались на операционную систему для получения dump анализа при сбое приложения (например, Windows Error Reporting) или использовали инструмент, такой как procdump, для доступа к dump при выполнении определенных критериев запуска.

До сих пор проблема с захватом dump анализа с помощью .NET на Linux заключалась в том, что захват дампов с помощью gcore или debugger приводил к очень большим сложностям, поскольку существующие инструменты не знали, какие страницы виртуальной памяти обрезать в .NET Core процессе.

Кроме того, было сложно проанализировать эти dump даже после того, как Вы их собрали, поскольку требовалось использовать debugger и настроить его для sos загрузки, debugger расширения для .NET.

dotnet-dump

В 3.0.0-preview5 добавлен новый инструмент, который собирает и анализирует dump процессы как на Windows, так и на Linux. 

dotnet-dump все еще находится в активной разработке, и в таблице ниже показано, какие функции и на каких ОС поддерживаются на данный момент.

  Windows OS X Linux
Collect
✅
❌
✅
Analyze
❌
❌
✅


Вы можете установить этот .NET инструмент, выполнив следующую команду

dotnet tool install --global dotnet-dump --version 1.0.3-preview5.19251.2

После того, как Вы установили dotnet dump, Вы можете записать dump процесс, выполнив следующую команду

sudo $HOME/.dotnet/tools/dotnet-dump collect -p <pid>

На Linux полученный dump можно проанализировать, загрузив его с помощью следующей команды

dotnet dump analyze <dump-name>

 

Для получения подробных инструкций о том, как использовать этот инструмент, перейдите на dotnet-dump readme. Для ознакомления с известными ограничениями dotnet-dump, перейдите на GitHub.

В заключение

 

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

 

Источник



Exception: Stack empty.
Posted on 12. March 2019

Как переносить настольные приложения на .NET Core 3.0

В этой статье будет рассмотрен перенос настольного приложения с .NET Framework на .NET Core. В качестве примера возьмем WinForms приложение. Шаги для WPF приложения схожи, различия рассмотрим по ходу. Также увидим как использовать WinForms designer в Visual Studio, хотя он находится в стадии разработки и еще не доступен для .NET Core проектов.

О примере

Для этого поста будет использовано игровое Memory-style board приложение. Оно состоит из WinForms UI (MatchingGame.exe) и библиотеки классов с игровой логикой (MatchingGame.Logic.dll), которые предназначены для .NET Framework 4.5. Здесь можно скачать образец. Итак, рассмотрим перенос проекта приложения на .NET Core 3.0, а также библиотеки классов на .NET Standard 2.0. Использование .NET Standard вместо .NET Core позволяет повторно использовать игровую логику для размещения приложения на других платформах, таких как iOS, Android или в вебе.

 

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

Пошаговый процесс

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

Прежде чем переносить приложение на .NET Core 3.0, подготовите следующее:

  1. Установите .NET Core 3 и Visual Studio 2019 Preview версию (Visual Studio 2017 поддерживает версии только до .NET Core 2.2).
  2. Начните с рабочего проекта. Убедитесь, что проект беспроблемно открывается, собирается и запускается.
  3. Обновите NuGet пакеты. Всегда рекомендуется использовать последние версии NuGet пакетов перед любым переносом. Если Ваше приложение ссылается на какие-либо NuGet пакеты, обновите их до последней версии. Убедитесь, что Ваше приложение успешно собрано. Если NuGet выдает ошибки, понизьте версию и найдите последнюю, которая не нарушает Ваш код.
  4. Запустите .NET Portability Analyzer, чтобы определить, существуют ли какие-либо API, от которых зависит Ваше приложение, и которые отсутствуют в .NET Core. Если таковые имеются, Вам необходимо провести рефакторинг своего кода, чтобы избежать зависимостей от API, не поддерживаемых в .NET Core. Иногда можно найти альтернативный API, который обеспечивает необходимую функциональность.
  5. Замените packages.config на PackageReference. Если используются NuGet пакеты, то нужно добавить те же NuGet пакеты в новый .NET Core проект. .NET Core проекты поддерживают только PackageReference для добавления NuGet пакетов. Чтобы переместить ссылки NuGet из packages.config в файл проекта, в обозревателе решений необходимо щелкнуть правой кнопкой на packages.config -> Migrate packages.config в PackageReference… Более детально об этом типе переноса можно ознакомиться по ссылке Migrate from packages.config to PackageReference.

 

Портирование основного проекта

Создание нового проекта
  • Создайте новое приложение того же типа (Console, WinForms, WPF, Class Library), что и приложение, которое нужно перенести, для .NET Core 3. На данный момент были сделаны демонстрационные Visual Studio шаблоны для десктопных проектов, которые находились в стадии разработки, поэтому использовалась консоль.
dotnet new winforms -o \MatchingGame.Core\
  • Скопируйте в файле проекта все внешние ссылки из старого проекта, например:
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
  • Начните сборку. На этом этапе, если пакеты, на которые Вы ссылаетесь, поддерживают только .NET Framework, Вы получите NuGet предупреждение. Если Вы не обновились к последней версии NuGet пакета на шаге 3, попробуйте определить, доступна ли последняя версия, поддерживающая .NET Core (.NET Standard), и повторите обновление. Если более новой версии нет, то .NET Framework пакеты все еще можно использовать, но можно получить ошибки времени выполнения, если эти пакеты имеют зависимости от API, не поддерживаемых в .NET Core. В таком случае рекомендуется сообщить автору NuGet пакета, что Вас заинтересовало бы обновление пакета до .NET Standard. Сделать это можно через контактную форму в NuGet галерее.
Быстрый способ (заменить существующий файл проекта)

Итак, быстрый способ переноса. Убедитесь, что у Вас есть копия текущего .csproj файла, возможно, Вам придется использовать его в будущем. Замените текущий .csproj файл .csproj файлом из проекта, созданного ранее, и добавьте вверху <PropertyGroup> следующее:

<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
Соберите приложение. Если ошибок не возникло, то перенос проекта на .NET Core 3 прошел успешно. Для перемещения зависимого (UI) проекта рекомендуется ознакомиться с разделом «Перенос пользовательского интерфейса»), чтобы узнать, как использовать Designer, ознакомьтесь с разделом «Использование WinForms Designer для проектов .NET Core».

Медленный путь (управляемый перенос)

Если система выдает ошибки, то нужно внести дополнительные корректировки. Здесь предоставлена информация о внесении изменений в код с возможными исправлениями для каждого вопроса. Шаги ниже также помогут лучше понять процесс переноса, поэтому, если быстрый способ помог, но Вам интересно узнать «почему и как», продолжайте читать.
  • Перейдите в.csproj файл в SDK-style. Чтобы переместить приложение в .NET Core, сначала нужно изменить файл проекта в SDK формате, поскольку старый формат не поддерживает .NET Core. Кроме того, SDK-style формат намного проще и с ним легче работать. Убедитесь, что копия текущего .csproj файла создана. Замените содержимое .csproj файла следующим. Для WinForms приложения:
  
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net472</TargetFramework>
    <UseWindowsForms>true</UseWindowsForms>
    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
  </PropertyGroup>
</Project></pre>
Для WPF приложения:

  
    <Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net472</TargetFramework>
    <UseWPF>true</UseWPF>
    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
  </PropertyGroup>
</Project>
Обратите внимание, что значение <GenerateAssemblyInfo> было установлено как false. В проектах нового стиля AssemblyInfo.cs генерируется автоматически по умолчанию. Так что, если проект уже содержит файл AssemblyInfo.cs файл (а он содержит), то необходимо отключить авто-генерацию или удалить файл.

Теперь скопируйте и вставьте все ссылки из старой версии .csproj файла в новую. Например:

Ссылка на NuGet пакет
 
<PackageReference Include="Microsoft.Windows.Compatibility" Version="2.0.1" />
Ссылка на проект
 
<ProjectReference Include="..\MatchingGame.Core\MatchingGame.Core.csproj" />

Проект должен успешно сформироваться, так как это просто новый способ написать то же самое. Если возникли какие-либо ошибки, то перепроверьте сделанные шаги.

Существует также сторонний инструмент CsprojToVs2017, который может выполнить преобразование. Но после его использования все равно может понадобиться удалить некоторые ссылки вручную, например:
<Reference Include="System.Data.DataSetExtensions"></Reference>
<Reference Include="Microsoft.CSharp"></Reference>
<Reference Include="System.Net.Http"></Reference>

  • Перейдите от .NET Framework к .NET Standard или .NET Core. После успешного преобразования библиотеки в SDK формат, ее можно перенастроить. В данном случае, необходимо, чтобы библиотека классов предназначалась для .NET Standard вместо .NET Core. Таким образом, она будет доступна из любой .NET реализации, если нужно отправить игру на другие платформы (например, iOS, Android или Web Assembly). Для этого замените данную строку
<TargetFramework>net472</TargetFramework>
на следующую

<TargetFramework>netstandard2.0</TargetFramework>
Создайте Ваше приложение. Если Вы используете API, которые не включены в .NET Standard, то могут возникнуть ошибки. Если ошибок нет, то следующие два шага можно пропустить.

  • Добавьте Windows Compatibility Pack для совместимости, если необходимо.Некоторые API, которые не включены в .NET Standard, доступны в Windows пакете совместимости. Если на предыдущем шаге были получены ошибки, то можно проверить, поможет ли Windows пакет совместимости. В рассматриваемом приложении была получена следующая ошибка «Имя реестра не существует в текущем контексте», поэтому в проект был добавлен Microsoft.Windows.Compatibility NuGet пакет. После установки ошибка исчезла.
  • Установите API Analyzer. API Analyzer, доступный в виде NuGet пакета Microsoft.DotNet.Analyzers.Compatibility, предупредит об использовании устаревших API или API, которые не поддерживаются на всех платформах (Windows, Linux, macOS). Если был добавлен пакет совместимости, то рекомендуется добавить и API Analyzer для отслеживания случаев использования API, которые не будут работать на всех платформах. На этом рассмотрение процесса переноса библиотеки классов на .NET Standard заканчивается. Если у Вас есть несколько проектов, которые ссылаются друг на друга, переносите их «снизу вверх», начиная с проекта, который не зависит от других. В данном примере также есть WinForms MatchingGame.exe проект, поэтому теперь необходимо выполнить аналогичные шаги для его переноса в .NET Core.
Перенос пользовательского интерфейса
  • Добавьте .NET Core UI проект. Внедрите в решение новый .NET Core 3.0 UI проект. На данный момент Visual Studio шаблоны для настольных приложений находятся в стадии разработки, поэтому можно просто использовать dotnet CLI.
dotnet new winforms -o \MatchingGame.Core\
Для WPF проектов можно использовать следующее:

dotnet new wpf -o \MatchingGame.Core\
После того, как был создан новый WinForms .NET Core проект, его необходимо добавить в Ваше решение.
  • Свяжите проекты. Сначала удалите все файлы из нового проекта (прямо сейчас он содержит общий Hello World код). Затем свяжите все файлы из существующего .NET Framework UI проекта с .NET Core 3.0 UI проектом, добавив в .csprojfile файл следующую команду.
    
<ItemGroup>
    <Compile Include="..\\**\*.cs" />
    <EmbeddedResource Include="..\\**\*.resx" />
</ItemGroup>
Если у Вас WPF приложение, также необходимо включить .xaml файлы:

  
<ItemGroup>
  <ApplicationDefinition Include="..\WpfApp1\App.xaml" Link="App.xaml">
    <Generator>MSBuild:Compile</Generator>
</ApplicationDefinition>
<Compile Include="..\WpfApp1\App.xaml.cs" Link="App.xaml.cs"></Compile>
</ItemGroup>

<ItemGroup>
  <Page Include="..\WpfApp1\MainWindow.xaml" Link="MainWindow.xaml">
    <Generator>MSBuild:Compile</Generator>
  </Page>
  <Compile Include="..\WpfApp1\MainWindow.xaml.cs" Link="MainWindow.xaml.cs" />
</ItemGroup>
  • Совместите пространство имен по умолчанию и имя сборки. Поскольку Вы ссылаетесь на файлы, созданные дизайнером (например, Resources.Designer.cs), то нужно убедиться, что версия Вашего .NET Core приложения использует то же пространство имен и то же имя сборки. Скопируйте следующие параметры из Вашего .NET Framework проекта:
<PropertyGroup>
    <RootNamespace><!-- (Your default namespace) --></RootNamespace>
    <AssemblyName><!-- (Your assembly name) --></AssemblyName>
</PropertyGroup>
  • Отключите AssemblyInfo.cs файл. Как было отмечено ранее, в проектах нового стиля AssemblyInfo.cs генерируется автоматически по умолчанию. В то же время AssemblyInfo.cs файл из старого WinForms проекта будет скопирован и в новый проект, так как все ** \ *.cs файлы были связаны на предыдущем шаге. Это приведет к дублированию AssemblyInfo.cs. Чтобы избежать этого в файле MatchingGame.Core проекта, для GenerateAssemblyInfo было установлено значение false.
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
  • Запустите новый проект. Установите новый .NET Core проект в качестве StartUp проекта и запустите его. Убедитесь, что все работает.
  • Скопируйте или оставьте ссылку. Теперь вместо связывания файлов можно скопировать их из старого .NET Framework UI проекта в новый .NET Core 3.0 UI проект. После этого предыдущий можно удалить.
Использование WinForms Designer для проектов .NET Core

Как было упомянуто выше, WinForms Designer для .NET Core проектов еще не доступен в Visual Studio. Однако есть два способа обойти данный вопрос: 

  1. Сохраните файлы связанными (просто не выполните предыдущий шаг) и скопируйте их, когда будет доступна designer поддержка. Таким образом, можно изменить файлы в старом .NET Framework WinForms проекте, используя designer. И изменения будут автоматически отражены в новом .NET Core WinForms проекте, поскольку они связаны между собой.
  2. Храните два файла проекта в той же директории, где и WinForms проект: старый .csproj файл из существующего .NET Framework проекта и новый .csproj файл в SDK-style нового .NET Core WinForms проекта. Нужно выгрузить и перезапустить проект с соответствующим файлом проекта в зависимости от того, хотите ли Вы использовать designer или нет.
Подведение итогов

В этой статье было показано, как перенести десктопное приложение, содержащее несколько проектов, из .NET Framework на NET Core. Обычно недостаточно просто перенастроить свои проекты на .NET Core. Также были описаны потенциальные проблемы, с которыми Вы можете столкнуться, и способы их решения. Кроме того, было рассмотрено, как можно использовать WinForms designer для портированных приложений, пока он еще не доступен для .NET Core проектов.



Exception: Stack empty.
Posted on 23. December 2018

.NET производительность в предварительной версии Visual Studio 2019

Наверняка Вы уже слышали о выпуске предварительного просмотра Visual Studio 2019. В этой статье будут рассмотрены улучшения для .NET разработчиков, которые затронули в первую очередь производительность. Полный список изменений можно найти здесь.

Поддержка Языка Regex

У постоянных выражений файлов в C# или Visual Basic теперь есть подсветка синтаксиса, диагностика компилятора и исправления кода. Эта поддержка синтаксического анализа распознает строки, переданные в regex конструктор, и строки, непосредственно предшествующие комментарию, содержащему строку `language=regex`. В этот выпуск включены следующие функции языка: классификация, сопоставление скобок, подсветка ссылок и диагностика компилятора.

Экспорт настроек редактора в Editorconfig

Теперь можно экспортировать настройки редактора в Editorconfig файл через Сервис> Параметры> Текстовый редактор> C#> Стиль кода с помощью кнопки «Создать .editorconfig файл, используя настройки».

Исправления и Рефакторинги Кода

В первом предварительном просмотре Visual Studio 2019 были добавлены несколько наиболее востребованных исправлений и рефакторингов кода. Рефакторинг и быстрые действия доступны с помощью горячих клавиш (Ctrl +.) или (Alt + Enter).

Foreach цикл для LINQ запроса

Foreach циклы к LINQ запросам или LINQ методам теперь объединяются с другими параметрами рефакторинга цикла, включая преобразование LINQ в Foreach цикл, For в Foreach цикл и Foreach в For цикл.


Добавление «Using» оператора к copy/paste


Преобразование анонимного типа в класс


Преобразование локальной функции в метод


Более новые исправления кода и рефакторинги:
  • Преобразование кортежа в именованную структуру.
  • Анализ мертвого кода неиспользуемых закрытых элементов с необязательным исправлением кода для удаления объявления неиспользованного элемента.
  • Создание метода деконструкции.
  • Добавление «await» там, где это подразумевается, но где нет предупреждения компилятора.
Ознакомиться со всеми исправлениями кода и рефакторингами для .NET можно здесь.

Индикатор работоспособности документа

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

«Find All» ссылки и поддержка CodeLens Razor

«Find All» ссылки (Shift-F12) и CodeLens отображают результаты из Razor (.cshtml) файлов в .NET Core проектах. Теперь Вы можете перейти к указанному коду в соответствующих Razor файлах.

Запуск тестов из Solution Explorer

Чтобы запустить или отладить тесты, можно просто щелкнуть правой кнопкой мыши на тестах, тестовых классах или тестовых проектах в Solution Explorer.

Попробуйте, как работает предварительный просмотр, оставляйте Ваши отзывы или вопросы о Visual Studio. В этом блог посте Вы можете изучить еще больше информации, а также посмотреть видео о других функциях Visual Studio 2019 Preview 1.

 



Exception: Stack empty.