Tuesday, January 29, 2019

Visual Studio 2019 Preview 2.0 and .NET Core Tooling Update

As you might already know, Visual Studio 2019 Preview 2.0 was released and there were a couple of nice features got introduced.

In this post, let’s have a quick peek on two of the most interesting things.

Double click and open .csproj file

This is really handy work. We usually interact a lot with .csproj files in the solution and so far what we used to do is, right click on the project and click on Edit .csproj.
Edit .csproj
And this not that user-friendly. What if we can simply double click on the project file to open it. That will be super easy, isn’t it? And with Visual Studio 2019 Preview 2.0, that’s possible. No more right clicking on the project and select Edit .csproj, just double click on the project and the project file gets opened.

New Integrated Console

Say you are trying or testing some piece of code, what we often do is creating a console application and write the code there (sometimes I use dotnetfiddle, but that’s for some basic code). And if you are just running the code and if you missed adding a Console.Read() at the end, the program will execute and the console will exit. But with the new integrated console, the program will execute and the console will stay open. And all the subsequent runs, the same window will be used, meaning you won’t have multiple consoles open for each session which can be annoying.
Microsoft Visual Studio Debug Console
And if you want to opt-out from having the console window opened, you can do so by going to Tools –> Options –> Debugging –> General and selecting Automatically close the console when debugging stops.
Automatically close the console when debugging stops
Hope this helps.

Happy Coding.

Regards,
Jaliya

Wednesday, January 9, 2019

.NET Core 2.2: Runtime Events

In this post let’s go through one of the features which got introduced with .NET Core 2.2 which is the ability to capture .NET Core runtime events within your .NET Core application.

Prior to .NET Core 2.2, these CoreCLR events were unable to be consumed within your .NET Core application, it was only available to be observed in ETW (Event Tracing for Windows) on Windows or from LTTng on Linux.

With .NET Core 2.2, these events are getting routed through an EventListener, so within your EventListener, you can decide what to do with it. It basically doesn’t matter on which OS you are on, it works on all Windows/MacOS and Linux.

Let’s have a look at an example. I have created an ASP.NET Core Web API Application targetting .NET Core 2.2.
<Project Sdk="Microsoft.NET.Sdk.Web">
 
  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
  </PropertyGroup>
  
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>
 
</Project>
There I have the following EventListener.
public class SimpleEventListener : EventListener
{
    private readonly ILogger<SimpleEventListener> _logger;
 
    public SimpleEventListener(ILogger<SimpleEventListener> logger)
    {
        _logger = logger;
    }
 
    // Called whenever an EventSource is created.
    protected override void OnEventSourceCreated(EventSource eventSource)
    {
        // Watch for the .NET runtime EventSource and enable all of its events.
        if (eventSource.Name.Equals("Microsoft-Windows-DotNETRuntime"))
        {
            EnableEvents(eventSource, EventLevel.Verbose, (EventKeywords)(-1));
        }
    }
 
    // Called whenever an event is written.
    protected override void OnEventWritten(EventWrittenEventArgs eventData)
    {
        // Write the contents of the event to the console.
        _logger.LogInformation($"ThreadID = {eventData.OSThreadId} ID = {eventData.EventId} Name = {eventData.EventName}");
 
        for (var i = 0; i < eventData.Payload.Count; i++)
        {
            string payloadString = eventData.Payload[i] != null ? eventData.Payload[i].ToString() : string.Empty;
            _logger.LogInformation($"\tName = \"{eventData.PayloadNames[i]}\" Value = \"{payloadString}\"");
        }
 
        _logger.LogInformation("\n");
    }
}

Now I am enabling the SimpleEventListener from Startup.ConfigureServices method.
public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
 
    ServiceProvider provider = services.BuildServiceProvider();
    var simpleEventListener = new SimpleEventListener(provider.GetRequiredService<ILogger<SimpleEventListener>>());
}

That’s it. Now if you run the application, you should be able to see all the CoreCLR events.
image
.NET Core 2.2: Visual Studio on Windows: CoreCLR Events
I just ran the same application inside MacOS, it works the same.
image
.NET Core 2.2: Rider on MacOS: CoreCLR Events
Now, if I change the target framework to 2.1 and return the application, we can’t see CoreCLR events.
image
.NET Core 2.1: Visual Studio on Windows: No CoreCLR Events
This is some awesome piece of work.

Happy Coding.

Regards,
Jaliya