• What's new in Visual Studio 2022

    I’m starting to compile some information for our next Adelaide .NET User Group meetup which is focusing on the launch of .NET 6 and Visual Studio 2022.

    First up, Visual Studio 2022. This is a consolidation of the points listed on the Visual Studio 2022 RC and Preview Release Notes. There’s lots more detail on that page.

    Once Visual Studio 2022 is launched (on November 8th), I’d expect https://docs.microsoft.com/en-au/visualstudio/releases/2022/release-notes?WT.mc_id=DOP-MVP-5001655 to be updated with a final summary.

    Visual Studio 2022 Splash Screen

    64-bit

    • devenv.exe is now 64-bit only

    .NET 6 SDK

    • The .NET 6 SDK (preview) is included in Visual Studio 2022
    • This release has basic support for .NET MAUI projects. Temporarily you have to install the .NET MAUI workload separately from .NET 6. See our .NET MAUI installation documentation for more information

    .NET Productivity

    • Introduce parameter refactoring can move a new parameter from the method implementation to its callers.
    • Track Value Source for data flow analysis
    • Option to underline variables that are re-assigned
    • Added search option in Generate Overrides dialog
    • Quick info for XML <code> tags now preserve whitespace and CDATA blocks
    • Find All References window will now group multi-target projects
    • Refactoring to remove repetitive types in Visual Basic
    • Go to Implementation will no longer navigate to members with abstract declarations that are also overridden.
    • Nullable reference types is now enabled by default for new .NET projects
    • C# 10.0 File-scoped namespace refactoring
    • Navigate to decompiled sources is now on by default
    • Refactoring to prefer null check over type check
    • XML comments will now automatically generate an <exception> tag when a method explicitly throws exceptions
    • Inheritance Margin is now enabled by default
    • Synchronize namespaces to match your folder structure from Solution Explorer
    • Configure background code analysis from Solution Explorer

    Azure Cloud Services

    • Azure Cloud Service (classic) and Azure Cloud Service (extended support) projects are now supported.

    C++

    • You can now build and debug natively on WSL2 without establishing a SSH connection. Both cross-platform CMake projects and MSBuild-based Linux projects are supported.
    • The v143 build tools are now available through the Visual Studio installer as well as the standalone build tools.
    • Visual Studio now supports the buildPresets.targets option in CMakePresets.json. This allows you to build a subset of targets in your CMake project.
    • The Project menu in CMake projects has been streamlined and exposes options to “Delete Cache and Reconfigure” and “View Cache”.
    • Code analysis now enforces that return values of functions annotated with _Check_return_ or _Must_inspect_result_ must be checked.
    • LLVM tools shipped with Visual Studio have been upgraded to LLVM 12. See the LLVM release notes for details.
    • Clang-cl support was updated to LLVM 12.
    • C++ AMP headers are now deprecated. Including <amp.h> in a C++ project will generate build errors. To silence the errors, define _SILENCE_AMP_DEPRECATION_WARNINGS.
    • The new Hot Reload experience is now available to native C++ applications when running under the debugger. For more information see our Hot Reload section below.
    • CMake Overview Pages have been updated to support CMakePresets.json.
    • You can now configure and build your CMake projects with CMake 3.21 and CMakePresets.json v3.
    • You can now debug processes running on a remote systems from Visual Studio with LLDB.
    • Made improvements in C++ IntelliSense when providing navigation and syntax highlighting for types from imported Modules and Header Units. This is an active area of investment for us, please continue to share your feedback on Developer Community using Help->Send Feedback.
    • Improved C++ IntelliSense performance by optimizing cached header usage and symbol database access, providing improved load times to get into your code.
    • The IntelliSense Code Linter for C++ is now on by default, providing instant as-you-type suggestions and fix suggestions for common code defects.
    • Updated to NDK r21 LTS in C++ Mobile Development workload.
    • Added support for gsl::not_null to code analysis.
    • Support for libfuzzer under the switch -fsanitize=fuzzer.
    • Hot Reload for C++ now supports CMake and OpenFolder projects.
    • Implemented /scanDependencies flag for outputting C++20 module dependencies for CMake projects as described in P1689r3. This is a step towards support for building modules-based projects with CMake and we are working on completing this support in later releases.
    • We have improved null pointer dereference detection in our code analysis tooling.
    • We have upgraded the version of CMake shipped with Visual Studio to version 3.21. See the CMake 3.21 release notes for details on what is available.
    • The MSVC toolset now defaults to SHA-256 source hashing in debug records. Previously, the toolset used MD5 for source hashing by default.
    • The Game development with C++ workload now installs the latest Unreal Engine with support with for Visual Studio 2022.

    Debugging & Diagnostics

    • Attach to process dialog improvements
    • Exception helper improvements
    • Force Run to Click
    • Memory Dump Diagnostic Analysis
    • Breakpoint Gutter improvements
    • Temporary Breakpoint
    • Drag and Drop Breakpoint
    • External Sources Node in Solution Explorer
    • Attach to process dialog improvements
    • Memory Dump Diagnostic Analysis
    • We have released a new type of breakpoint called Dependent Breakpoint, which allows you to configure a breakpoint to be enabled only if another breakpoint is first hit.
    • We have added more updates to the External Sources node, you can now see the module under the sub-node “Modules without Sources” and load the symbols form solution explorer itself.

    Editor

    • Added subword navigation
    • Autosave is now available as a preview feature
    • Multi-caret copy/paste experience

    Extensibility

    • VS SDK contains several breaking changes and Visual Studio 2019 extensions will not work in 2022. See VSSDK documentation for more information.
    • VS SDK Reference assemblies are no longer installed to the VSSDK\VisualStudioIntegration\Common\Assemblies folder. If your build was relying on these assemblies, please migrate your project to use NuGet packages instead. For offline scenarios:
      • Keep an in-org nuget feed from which to restore the nuget packages.
      • Check in the binaries.
    • Added ILanguageClient breaking change fixes
    • Removed APIs from Microsoft.VisualStudio.Language.Client assemblies

    Git Tooling

    • Removed the ability to revert back to the Team Explorer Git UI, making the new Git experience the only available built-in tooling.
    • Removed the option to install the GitHub extension from the Visual Studio Installer.
    • Basic multi-repo support under a preview flag for any Solution that spans different repositories (i.e. Solutions with projects hosted in different Git repositories)
    • Publish to Azure DevOps is now fully supported in the create git repository experience
    • Status bar enhancements including a new ability to view and open repositories from an empty VS
    • Commit details enhancements including a more responsive and user friendly UI
    • The overflow menu on the Git Changes window is now available for local only repositories with additional git operations

    Help Menu

    • During 17.0 we have remodelled the Help Menu! The updated menu highlights Get Started material and helpful Tips/Tricks. It also provides more collaboration with our development team by adding things such as access to Developer Community, Release Notes, the Visual Studio product Roadmap, and our Social Media pages. We want developers to make the most out of their subscriptions so check out your subscription benefits and other details via the new My Subscription menu item!

    Hot Reload

    • .NET Hot Reload is now available in Visual Studio 2022 when running your app using the debugger (F5) through the new ‘apply code changes’ button. With Hot Reload you can edit your running applications code files and, in many cases, - apply those code changes without having to first pause the apps execution (as was previously required by edit and continue capability). With Hot Reload our goal is to save you as many app restarts as possible between edits, making you - more productive by reducing the time you spend building/restarting your application as you continue to build your app.
    • Hot Reload (for both .NET and C++ code) makes it possible to make many types of code edits to your running app and apply them without needing to pause the apps execution with something like a breakpoint. In this release we continue to - improve this feature, highlights include: Support for C++, .NET Hot Reload when running without debugger (CTRL-F5), support for more types of edits and more.
    • .NET/C++ Hot Reload - Various changes such as more supported edits, improvements for ASP.NET developers improvements to CTRL-F5 scenario and more.
    • Improvements to user experience (new button with options), apply changes on save and settings
    • Support for Hot Reload .NET MAUI apps (iOS, Android and WinUI)
    • Improvements to ASP.NET scenarios
    • More edits now supported
    • XAML Hot Reload
      • XAML Hot Reload Changes - Minor changes to in-app toolbar and settings
      • Improved support for XAML Hot Reload for .NET MAUI apps
      • Improved support for using both XAML and .NET Hot Reload in the same session for WPF and WinUI apps

    IntelliCode

    • Whole line auto completion

    JavaScript/TypeScript

    • We have released a new JavaScript/TypeScript project type that builds standalone JavaScript/TypeScript projects with additional tooling. You will be able to create Angular and React projects in Visual Studio using the framework version installed on your computer.
    • NPM GUI available, so you can now download NPM modules the same way you download Nuget packages

    Programming languages

    • C#10

    Razor (ASP.NET Core) Editor

    • Hot Reload support in Razor files
    • Performance improvements
    • Formatting and indentation enhancements
    • New Razor editor colors
    • TagHelpers are now colorized and have quick info classification support and completion tooltips
    • Angle brace highlighting and navigation for Razor constructs
    • Comments now have auto-completion, smart indentation, auto-inclusion of commenting continuations, and block - comment navigation
    • Reduced UI freezes and improved performance on solution startup
    • Faster semantic colorization up to 2x in some solutions
    • F7 (view code) support in Razor files
    • Snippet support in razor files which will complete a snippet session with a single tab instead of pressing - tab-tab
    • Better formatting in @code blocks when there’s nested HTML and Razor Components

    Test tools support

    • New versions of the test platform starting with 17.0 will not be able to run Generic tests and Ordered tests. These specific features only shipped as part of an early version of MSTestv1 and are not included in MSTestv2. We see very low usage of these features and ordered tests is now considered contrary to best testing practices.
    • Some test experiences will not be available in 17.0 Preview 1 including creating new TestSettings files and the TestSettings editor. Test runs will still be able to use TestSettings files, however TestSettings was replaced with RunSettings and we encourage users to migrate improved performance and functionality. Read more.
    • Coded UI Tests and Web Load Tests support will not arrive in 17.0 preview 1 as we are still working on porting these experiences to Visual Studio 2022. We do plan to support them in subsequent previews, though we strongly encourage users to move off Coded UI Test and Web Load Test. These technologies were officially deprecated in 2019 and we do plan to remove them from the product when we can minimize the impact to users.
    • Hot reload is now available in your test experience! Speed up your test runs by not requiring full builds in between test runs after minor code edits.
    • Remote Testing - Debugging remote environments connected with docker and wsl is now available. You can also debug over SSH connections if you are connected to linux. For setup instructions see the details in the Preview 2 release notes.
    • Show in Test Explorer
    • Web Load Test and Coded UI Test support updates

    Toolbox population for UWP Extension SDKs

    • UWP Extension SDKs are now required to explicitly declare the types that they wish to appear in the Toolbox by listing them in their SdkManifest.xml file. The behavior of older versions of Visual Studio is unchanged; they will ignore the list of controls in the manifest and instead dynamically enumerate the control types in the SDK’s assemblies.

    Trusted Locations

    • We have revamped the “Trust Settings” functionality and can now show a warning whenever untrusted code (e.g. files, projects or folders) is about to be opened inside the IDE.
    • Added support for Git repositories as trusted locations
    • Trust checks are now done at the solution folder level
    • User created projects are automatically added to the trusted list
    • Users can skip trust checks on temporary locations created by Visual Studio
    • Added Group Policy support as a way to manage the trust functionality

    User Interface

    • The default icons have been updated and refreshed.
    • As part of our goal to refresh the user interface for Visual Studio 2022, the default dark theme has been refreshed to improve contrast and assist in navigation and way-finding.
    • You can now sync your Visual Studio theme with your Windows OS theme - if you have a Light system theme, Visual Studio’s theme will be Blue. If you have a Dark system theme, Visual Studio’s theme will be Dark. This can be enabled via Tools > Options > General > Use system settings.

    Web Tools

    • The Publish summary page now has actions to start / stop remote debugging and profiling under the ‘…’ menu on the top right corner of the ‘Hosting’ section
    • The Connected Services page now has an action to launch Storage Explorer
    • The “ASP.NET Core Empty” template that comes with .NET 6 is using the new ‘minimal APIs’ paradigm for which we have started to add support

    WPF XAML Designer for .NET Framework

    • The current WPF XAML Designer for .NET Framework is replaced with a new WPF XAML Designer for .NET Framework, based on the same architecture used for the WPF XAML Designer for .NET (.NET Core).
    • The Visual Studio experience will look the same, but third-party control vendors need to support the new extensibility model since the previous model based on .design.dll and Microsoft.Windows.Design.Extensibility is deprecated. If you already created a .designtools.dll extension for .NET (.NET Core), that same extension will work for the new WPF XAML Designer for .NET Framework.

    XAML Live Preview

    • XAML Live Preview is now available for WPF developers as a first preview of this new experience. With Live Preview we enable the ability to capture a desktop apps UI and bring it into a docked window within Visual Studio, making it easier to use XAML Hot Reload to change the app and easily see the changes as you make them. This feature improves the XAML Hot Reload experience on a single screen device, while also making it possible to polish the apps UI with tools such as deep zooming, rulers, element selection and info tips.
    • Support added for .NET MAUI & Xamarin.Forms apps (Android Emulator)
    • Support added for WinUI 3 and UWP apps

    XAML Sample Data

    • Design-Time Sample Data will now be added by default when creating DataGrid, ListBox, and ListView controls from the toolbox in WPF applications. To disable this behaviour, uncheck ‘Automatically add sample data on element creation’ under Tools -> Options -> XAML Designer.

  • The fastest Contains() in .NET - Part 2

    A follow-up to my recent post about The fastest Contains() in .NET.

    John Merchant pointed out that there’s more detail on the Microsoft Docs site for the Contains() method for each of these types, which includes the Big O notation.

    eg.

    Method Order
    List<T>Contains(T) O(n)
    SortedSet<T>Contains(T) O(log n)
    HashSet<T>Contains(T) O(1)

    Sometimes it pays to read the documentation!

  • The fastest Contains() in .NET

    I was working on some code recently. It had some slow bits that I knew about, but I was really surprised when I noticed the log entries before and after a single line were 8 minutes apart!

    The line was similar to this:

    var matching = source.Where(x => other.Contains(x.Key)).ToList();
    

    Where source is a List<T> of custom class that includes a string property Key, and other is type List<string>.

    The line seems pretty innocuous. The only thing I could think of was that both lists contained quite a few items. I reasoned that in that case the Contains() may not be super efficient, as in the worse case it would have to compare every item in other list to the Key value only to find no matches. Maybe an alternative data structure to List<T> might perform better?

    If the list was sorted, then I figured that should make it it faster for searching, so I tried using SortedSet<T>. Being a ‘Set’ based type, it also eliminates duplicate values, so that could help. The next run, that code only took 4 seconds. Awesome, let’s ship it!

    Such a simple thing, but hey wouldn’t that make a good blog post. Why yes I think it would! But to make a decent post I think I need a better comparison than 8 minutes vs 4 seconds. So I created a simple reproduction of the scenario and made use of BenchmarkDotNet to get some statistics.

    In building the benchmark code, I thought it would not only be interesting to compare performance over the 3 most recent .NET runtimes, but also to add one more collection type HashSet<T> to the mix (and what a revelation that was!)

    The source code for the benchmarks can be found at https://github.com/flcdrg/list-performance.

    Here’s the raw results:

    BenchmarkDotNet=v0.13.1, OS=Windows 10.0.19043.1288 (21H1/May2021Update)
    11th Gen Intel Core i7-1185G7 3.00GHz, 1 CPU, 8 logical and 4 physical cores
    .NET SDK=6.0.100-rc.2.21505.57
      [Host]        : .NET 6.0.0 (6.0.21.48005), X64 RyuJIT
      .NET 5.0      : .NET 5.0.11 (5.0.1121.47308), X64 RyuJIT
      .NET 6.0      : .NET 6.0.0 (6.0.21.48005), X64 RyuJIT
      .NET Core 3.1 : .NET Core 3.1.20 (CoreCLR 4.700.21.47003, CoreFX 4.700.21.47101), X64 RyuJIT
    
    Method Job Runtime Mean Error StdDev
    AList .NET 5.0 .NET 5.0 889,075.6 µs 14,010.42 µs 13,105.35 µs
    ASortedSet .NET 5.0 .NET 5.0 13,352.2 µs 211.94 µs 187.88 µs
    AHashSet .NET 5.0 .NET 5.0 788.3 µs 6.43 µs 6.01 µs
    AList .NET 6.0 .NET 6.0 691,480.0 µs 10,067.18 µs 9,416.85 µs
    ASortedSet .NET 6.0 .NET 6.0 12,775.4 µs 192.49 µs 180.05 µs
    AHashSet .NET 6.0 .NET 6.0 794.5 µs 6.19 µs 5.79 µs
    AList .NET Core 3.1 .NET Core 3.1 943,716.1 µs 6,523.18 µs 6,101.79 µs
    ASortedSet .NET Core 3.1 .NET Core 3.1 12,686.2 µs 143.02 µs 133.78 µs
    AHashSet .NET Core 3.1 .NET Core 3.1 957.7 µs 8.09 µs 7.57 µs

    I copied the data into Excel to generate some graphs.

    First off, let’s compare the three collection types across a single runtime (.NET 6 RC.2)

    Chart comparing all three collection types running on .NET 6 RC2

    So List<T> is the worst, by a lot. So much that it doesn’t fit that well on the chart! SortedSet<T> was a better choice, but look - HashSet<T> beats them both comfortably.

    Ok, so HashSet<T> would have been a better choice. I’ll remember that for next time.

    But while we’re here, let’s use this as a useful glimpse into how collection performance has (mostly) improved over time.

    List<T> has got better from .NET Core 3.1 to .NET 5 and now .NET 6

    Chart comparing List<T> on the three runtimes

    Likewise, HashSet<T> made improvements from 3.1 to 5, with a tiny (possibly insignificant) regression for 6.

    Chart comparing HashSet<T> on the three runtimes

    The curious one is SortedSet<T>. It got worse in .NET 5, but clawed back some ground in .NET 6, though not quite back to 3.1 levels.

    Chart comparing SortedSet<T> on the three runtimes

    As to what’s behind the performance changes, a comparison of the source code for each type and reviewing any changes between .NET versions would give some clues - if the changes were insignificant then that does hint at underlying runtime improvements being the cause.

    List<T> is such a useful, general purpose collection type. I use it a lot. But after seeing this I’ll keep in mind that it is worth checking performance and that if necessary there are more specialised types that can perform a lot better if they’re able to be used.