Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What's new in .NET 6 Preview 5 #6099

Closed
leecow opened this issue Mar 29, 2021 · 26 comments
Closed

What's new in .NET 6 Preview 5 #6099

leecow opened this issue Mar 29, 2021 · 26 comments
Milestone

Comments

@leecow
Copy link
Member

leecow commented Mar 29, 2021

What's new in .NET 6 Preview 5

This issue is for teams to highlight work for the community that will release .NET 6 Preview 5.

To add content, use a new conversation entry. The entry should include the team name and feature title as the first line as shown in the template below.

## Team Name: Feature title

[link to the tracking issue or epic item for the work]

Tell the story of the feature and anything the community should pay particular attention 
to be successful using the feature.

Preview 1: #5853
Preview 2: #5889
Preview 3: #5890
Preview 4: #6098
Preview 5: #6099

@tannergooding
Copy link
Member

tannergooding commented Jun 4, 2021

Parsing of BigIntegers from both decimal and hexadecimal strings was improved: dotnet/runtime#47842

We saw improvements of up to 89%: DrewScoggins/performance-2#5765

Provided by community: jfd16

@tannergooding
Copy link
Member

Inlining of certain methods involving SIMD or HWIntrinsics should now have improved codegen and perf.

We saw improvements of up to 95%: DrewScoggins/performance-2#5581

@tannergooding
Copy link
Member

Vector<T> now supports the nint and nuint primitive types added in C# 9: dotnet/runtime#50832

This should make it simpler to SIMD code involving pointers or platform dependent lengths.

@RussKie
Copy link
Member

RussKie commented Jun 4, 2021

Windows Forms has received a new API Application.SetDefaultFont that allows setting an application-wide default font: dotnet/winforms#4911

@bartonjs
Copy link
Member

bartonjs commented Jun 4, 2021

.NET Cryptography on Linux supports using OpenSSL 3 as the native provider. The any-distro "portable" builds will try OpenSSL 3 before the previous versions.

@bartonjs
Copy link
Member

bartonjs commented Jun 4, 2021

The ChaCha20/Poly1305 algorithm now has representation in System.Security.Cryptography via the new ChaCha20Poly1305 class. OS support is required for this type (check the static IsSupported property). Windows: build 20142 or higher (currently requires the Dev "insider" channel). Linux: requires OpenSSL 1.1 or higher.

dotnet/runtime#52030 (Windows). Linux support was enabled by community member vcsjones in dotnet/runtime#52522.

@AaronRobinsonMSFT
Copy link
Member

Interop: Objective-C interoperability support

API: dotnet/runtime#44659
Feature flag for NSAutoreleasePool support.

The .NET Interop team worked with the Xamarin owners to enable the Xamarin.MacOS libraries to run on top of CoreCLR. Along with providing an explicit API we also added a feature flag for implicitly adding a NSAutoreleasePool instance to all managed threads. Full details on this can be found at dotnet/designs.

@marcpopMSFT
Copy link
Member

.NET SDK Optional Workload improvements

Building on the work that released in preview 4 for optional workloads, we've added two additional features.
dotnet workload list will let you see what workloads you have installed in the .NET SDK you are using
dotnet workload update will update all installed workloads to the newest available version.

It will query NuGet.org for a new Workload Manifest for all workloads, update the Manifests, and download new versions of the installed workloads, and then remove all old versions of the workload

@CarnaViire
Copy link
Member

CarnaViire commented Jun 7, 2021

Networking: WebSocket Compression

User Story: dotnet/runtime#20004
API: pt.1 dotnet/runtime#31088 (comment) pt.2 dotnet/runtime#31088 (comment)

This is an implementation of permessage-deflate extension for WebSockets, RFC 7692. It allows compressing WebSockets message payloads using DEFLATE algorithm. This feature was one of the top user asks on GitHub for Networking.

Most importantly, this is a big, complex and high-quality community contribution by @zlatanov.

It was a long journey (3 months of work) and we faced several problems along the way.

First, we realized that using compression together with encryption may lead to security implications, like CRIME/BREACH attacks. It means that a secret cannot be sent together with user-generated data in a single compression context, otherwise that secret could be extracted. To bring user's attention to these implications and help them weigh the risks, we renamed our API to DangerousDeflateOptions. We also added ability to turn off compression for specific messages, so if the user would want to send a secret, they could do that securely without compression.

Second, we stumbled upon a bug in zlib-intel implementation, that only manifested itself if a window used was not a maximal one (windowBits < 15). Once again, thanks to @zlatanov for going above and beyond to locate and fix the bug.

There was also a follow-up by @zlatanov that reduced the memory footprint of the WebSocket when compression is disabled by about 27%.

Enabling the compression from the client side is easy, see the example below. However, please bear in mind that the server can negotiate the settings, e.g. request smaller window, or deny the compression completely.

var cws = new ClientWebSocket();
cws.Options.DangerousDeflateOptions = new WebSocketDeflateOptions()
{
    ClientMaxWindowBits = 10,
    ServerMaxWindowBits = 10
};

WebSocket compression support was also recently added to ASP.NET Core dotnet/aspnetcore#2715 but will only be part of the upcoming previews.

@pgovind
Copy link

pgovind commented Jun 8, 2021

The [RequiresPreviewFeatures] attribute was created in S.P.CoreLib.

User Story: https://github.com/dotnet/designs/blob/main/accepted/2021/preview-features/preview-features.md

While the story is not complete yet, work is underway to implement the analyzer and sdk work needed to fully flesh out the feature. This brings dotnet 1 step closer in allowing developers to ship preview features in the apps.

@tarekgh
Copy link
Member

tarekgh commented Jun 8, 2021

System.Diagnostics Metrics support

User Story: dotnet/runtime#44445
Design Document: https://github.com/dotnet/designs/blob/main/accepted/2021/System.Diagnostics/Metrics-Design.md

The new exposed APIs is implementing the OpenTelemetry APIs specification. The Metrics APIs are designed explicitly for processing raw measurements, generally with the intent to produce continuous summaries of those measurements, efficiently and simultaneously. The APIs include the Meter class which can be used to create instrument objects (e.g. Counter). The APIs expose four instrument classes: Counter, Histogram, ObservableCounter, and ObservableGauge to support different metrics scenarios. Also, the APIs expose the MeterListener class to allow listening to the instrument's recorded measurement for aggregation and grouping purposes.

Library Measurement Recording Example

    Meter meter = new Meter("io.opentelemetry.contrib.mongodb", "v1.0");
    Counter<int> counter = meter.CreateCounter<int>("Requests");
    counter.Add(1);
    counter.Add(1, KeyValuePair.Create<string, object>("request", "read"));

Listening Example

    MeterListener listener = new MeterListener();
    listener.InstrumentPublished = (instrument, meterListener) =>
    {
        if (instrument.Name == "Requests" && instrument.Meter.Name == "io.opentelemetry.contrib.mongodb")
        {
            meterListener.EnableMeasurementEvents(instrument, null);
        }
    };
    listener.SetMeasurementEventCallback<int>((instrument, measurement, tags, state) =>
    {
        Console.WriteLine($"Instrument: {instrument.Name} has recorded the measurement {measurement}");
    });
    listener.Start();

OpenTelemetry .NET implementation will depend on these exposed APIs to support the end-to-end Metrics observability scenarios.

@JulieLeeMSFT
Copy link
Member

CodeGen

Community contributions (@SingleAccretion)

Dynamic PGO dotnet/runtime#43618

JIT Loop Optimizations dotnet/runtime#43549

LSRA dotnet/runtime#43318

Keep Structs in Register dotnet/runtime#43867

Optimizations & Debugging experience

@Anipik
Copy link
Contributor

Anipik commented Jun 9, 2021

Package Validation

User Story: #5700
Blog Post: https://aka.ms/packageValidationPreview5

Package Validation tooling will allow library developers to validate that their packages are consistent and well-formed. It involves validating that there are no breaking changes across versions. It will validate that the package have the same set of publics apis for all the different runtime-specific implementations. It will also help developers to catch any applicability holes.

@lateralusX
Copy link
Member

lateralusX commented Jun 10, 2021

Diagnostics (EventPipe/DiagnosticsServer) - MonoVM

A lot of diagnostics features have been added into MonoVM since beginning of .net6, enabling features like managed EventSource/EventListener, EventPipe and DiagnosticsServer, opening up capabilities to use diagnostics tooling like dotnet-trace, dotnet-counters, dotnet-stackwalk targeting apps running on mobile devices (iOS/Android) as well as desktop. This in turn opens up ability to analyse nettrace files generated by MonoVM in tools like PrefView/SpeedScope/Chronium, https://docs.microsoft.com/en-us/dotnet/core/diagnostics/dotnet-trace#dotnet-trace-convert, or writing custom parsers using libraries like https://www.nuget.org/packages/Microsoft.Diagnostics.Tracing.TraceEvent/ as described here, https://github.com/dotnet/diagnostics/blob/main/documentation/diagnostics-client-library-instructions.md.

The following things are currently included/done so far, this is far from an exclusive list, but should highlight the bigger items. We continue to include more features going forward, primarily focusing on SDK integration and adapting more native runtime events Microsoft-Windows-DotNETRuntime into MonoVM enabling more events in nettrace files.

  • Share native EventPipe/DiagnosticsServer library between MonoVM and CoreCLRC. A full port of CoreCLR EventPipe/DiagnosticsServer C++ library into C was done during fall 2020 (https://github.com/dotnet/runtime/tree/main/src/native/eventpipe), fully sharable between runtimes, using runtime shim layer to keep runtime specific PAL layers, containers and other artefacts intact. This enabled us to share the majority of the library but still keeping runtime specific implementations when needed.
  • Add TCP/IP support into DiagnosticsServer and build MonoVM iOS/Android runtime packs leveraging that configuration. Needed in order to support mobile platforms together with diagnostics tooling (utilizing a new diagnostic tool, dotnet-dsrouter, IPC->TCP/IP router).
  • BCL EventSources runs on MonoVM emitting events into EventPipe.
  • BCL Runtime counters emitted by System.Diagnostics.Tracing.RuntimeEventSource wired up on MonoVM, consumable from tools like dotnet-counters.
  • Custom EventSources runs on MonoVM, emitting custom events into EventPipe, consumable from tools like dotnet-trace.
  • Custom event counters runs on MonoVM, emitting custom counter events into EventPipe, consumable from tools like dotnet-counters.
  • Sample profiler is implemented on MonoVM emitting events into EventPipe. Opens up abilities to do CPU profiling on MonoVM using dotnet-trace as described here, https://docs.microsoft.com/en-us/dotnet/core/diagnostics/debug-highcpu
  • Implementation of dotnet-dsrouter diagnostics tool, enables use of existing diagnostic tooling like, dotnet-trace, dotnet-counters, dotnet-stackwalk together with MonoVM running on mobile targets, without any need to change existing tooling. dotnet-dsrouter runs a local IPC server routing all traffic from diagnostic tooling over to DiagnosticsServer running in MonoVM on simulator/device.
  • Implementation of EventPipe/DiagnosticsServer in MonoVM using component based architecture, https://github.com/dotnet/runtime/blob/main/docs/design/mono/components.md. In preview 5, both iOS and Android are using static components (using static mono runtime, all statically linked into final app). Android will however change to dynamic components in preview 6, inline with SDK usage patterns. Since mobile platforms have different use cases and size restrictions compared to desktop, using a component based architecture for EventPipe/DiagnosticsServer on MonoVM gives us ability to ship one runtime pack and based on app build configuration, include/exclude specific components at app build time, open up ability to use diagnostics during development/testing but exclude it in final build (send to app store), reducing size and prevent app to include unwanted features in retail version.
  • Implementation/extension of diagnostics environment based file session, https://github.com/dotnet/runtime/blob/main/docs/design/mono/diagnostics-tracing.md#application-running-single-file-based-eventpipe-session.
  • Validating on iOS/Android simulator/emulator using sample apps (https://github.com/dotnet/runtime/tree/main/src/mono/sample/iOS, https://github.com/dotnet/runtime/tree/main/src/mono/sample/Android) toghether with diagnostics tooling,dotnet-trace, dotnet-counters and dotnet-dsrouter.

Part of iOS start up CPU sampling session viewed in SpeedScope:

speedscope-p5

Android CPU sampling viewed in PerfView (main thread in infinite sleep)

prefview-p5

What's next (P6/P7):

  • Switch over using dynamic components on Android.
  • iOS/Android SDK integration.
  • Include more native runtime events (JIT stats, loader, threads, exceptions, module/assembly/method load/unload, monitor contention etc).
  • Continue simplify dsrouter scenarios for mobile use cases.
  • Simplify sample apps (https://github.com/dotnet/runtime/tree/main/src/mono/sample/iOS, https://github.com/dotnet/runtime/tree/main/src/mono/sample/Android) use of component build and diagnostics server.
  • Adapt low level mono profiler events into EventPipe. Currently a number of events are mapped to events in Microsoft-Windows-DotNETRuntime, but not all have clear 1:1 mappings. Adding option to do a full set of mono profiler events into mono specific events (~60 profiler events to cover all) in Microsoft-Windows-DotNETRuntime will give us full ability to replace existing mono log profiler and we could add support for GC memory diagnostics using dotnet-gcdump out of band, adapting a memory graph using MonoVM GC events, or just dump GC trace stream to disk as a great starting point.

@MihaZupan
Copy link
Member

Networking: Socks proxy support

Issue: dotnet/runtime#17740
PR: dotnet/runtime#48883

Adding support for socks proxies (Socks4, Socks4a, Socks5) has been a long-standing feature request from the community (issue is 5 years old). Among other things, it enables users to test external connections via SSH or connect to the Tor network from .NET directly.

The implementation came from a community contributor @huoyaoyuan!

It does not impact the public API, but WebProxy now accepts socks schemes

var handler = new HttpClientHandler
{
    Proxy = new WebProxy("socks5://127.0.0.1", 9050)
};
var httpClient = new HttpClient(handler);

@maryamariyan
Copy link
Member

maryamariyan commented Jun 10, 2021

Microsoft.Extensions.Hosting

Hosting - ConfigureHostOptions API

Prior to Preview 5, configuring the host options, (e.g. configuring the shutdown timeout) would looks like this:

using var host = new HostBuilder()
    .ConfigureServices(servies =>
    {
        servies.Configure<HostOptions>(o =>
        {
            o.ShutdownTimeout = TimeSpan.FromMinutes(10);
        });
    })
    .Build();

host.Run();

to make this setup less convoluted, in Preview 5, we added a new ConfigureHostOptions API on IHostBuilder:

using var host = new HostBuilder()
    .ConfigureHostOptions(o =>
    {
        o.ShutdownTimeout = TimeSpan.FromMinutes(10);
    })
    .Build();

host.Run();

Microsoft.Extensions.DependencyInjection

Dependency Injection - CreateAsyncScope APIs

You might have noticed that disposal of a service provider which is wrapped in a using statement, will throw an InvalidOperationException when it happens to register an IAsyncDisposable service:

using System;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;

await using var provider = new ServiceCollection()
        .AddScoped<Foo>()
        .BuildServiceProvider();

using (var scope = provider.CreateScope())
{
    var foo = scope.ServiceProvider.GetRequiredService<Foo>();
}

class Foo : IAsyncDisposable
{
    public ValueTask DisposeAsync() => default;
}

We workaround this today by casting the returned scope to IAsyncDisposable:

var scope = provider.CreateScope();
var foo = scope.ServiceProvider.GetRequiredService<Foo>();
await ((IAsyncDisposable)scope).DisposeAsync();

To mitigate such issues, with Preview 5 release you will notice new CreateAsyncScope APIs to help simplify this code snippet to:

await using (var scope = provider.CreateAsyncScope())
{
    var foo = scope.ServiceProvider.GetRequiredService<Foo>();
}

@layomia
Copy link

layomia commented Jun 11, 2021

Compile-time source generation for System.Text.Json

User stories: dotnet/runtime#1568, dotnet/runtime#45441

Dedicated preview 5 blog post: https://aka.ms/JsonSourceGenPreview5

Background

Source generators allow developers to generate C# source files that can be added to an assembly during the course of compilation. Generating source code at compile time can provide many benefits to .NET applications, including improved performance. In .NET 6, we are releasing a new source generator as part of System.Text.Json. The JSON source generator works in conjuction with JsonSerializer, and can be configured to generate optimized serialization logic, type-metadata initialization logic, or both. Executing this generated code can provide the following benefits to applications that use System.Text.Json:

  • Improve serialization throughput
  • Reduce start-up time
  • Reduce private memory usage
  • Eradicate runtime use of System.Reflection and System.Reflection.Emit
  • Provide safe trimming with ILLinker
    • Reduce application size

Generating optimized serialization logic

JsonSerializer is a powerful tool which has many features (and even more coming!) that can influence the serialization of .NET types into the JSON format. It is fast, but can have some performance overhead when only a subset of features are needed for a serialization routine. Pre-generating source code that uses Utf8JsonWriter directly, and accounts for only the features needed by the routine can help improve performance.

We have defined a set of JsonSerializer features that we can honor in pre-generated serialization code. These features can be specified to the source generator ahead of time, to avoid extra checks at runtime.

Given a simple type:

namespace Test
{
    internal class JsonMessage
    {
        public string Message { get; set; }
    }
}

We can configure the source generator to generate serialization logic for instances of this type, given some pre-defined serializer options:

using System.Text.Json.Serialization;

namespace Test
{
    [JsonSerializerOptons(
        DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault,
        IgnoreRuntimeCustomConverters = true,
        NamingPolicy = JsonKnownNamingPolicy.BuiltInCamelCase)]
    [JsonSerializable(typeof(JsonMessage), GenerationMode = JsonSourceGenerationMode.Serialization)]
    internal partial class JsonContext : JsonSerializerContext
    {
    }
}

The source generator would then augment the partial class provided by the user with the following shape:

internal partial class JsonContext : JsonSerializerContext
{
    public JsonContext Default { get; }

    public JsonTypeInfo<JsonMessage> JsonMessage { get; }

    public JsonContext(JsonSerializerOptions options) { }

    public override JsonTypeInfo GetTypeInfo(Type type) => throw null;
}

To serialize instances of this type and get the best possible performance, one could invoke the generated code as follows:

using MemoryStream ms = new();
using Utf8JsonWriter writer = new(ms);

JsonContext.Default.JsonMessage.Serialize!(writer, new JsonMessage { "Hello, world!" });
writer.Flush();

// Writer contains:
// {"message":"Hello, world!"}

The generate code can also be passed to JsonSerializer, to integrate it with rich functionality provided by the serializer, e.g. configuring a Utf8JsonWriter instance for serialization.

JsonSerializer.Serialize(jsonMessage, JsonContext.Default.JsonMessage);
JsonSerializer.Serialize(jsonMessage, typeof(JsonMessage), JsonContext.Default);

This source generation mode is only available for serialization, but not deserialization. A mode that generates optimized deserialization logic using Utf8JsonReader can be provided in the future.

Generating type-metadata initialization logic

In some scenarios, we may want benefits of JSON source generation, but our serialization feature requirements might not be compatible with what can be honored in the generator mode that generates serialization logic. For instance, reference handling and async serialization are two features that the source generator does not provide optimized serialization logic for. The generator provides a different mode, where instead of generating serialization logic, we can generate type-metadata initialization logic. This mode can provide all the afforementioned benefits of source generation, with the exception of improved serialization throughput. This mode can also provide benefits when deserializing JSON payloads.

In previous versions of System.Text.Json, serialization metadata could only be computed at runtime, during the first serialization or deserialization routine of every type in any object graph passed to the serializer. At a high level, this metadata includes delegates to constructors, property setters and getters, along with user options indicated at both runtime and design (e.g. whether to ignore a property value when serializing and it is null). After this metadata is generated, the serializer performs the actual serialization and deserialization. The generation phase is based on reflection, and is computationally expensive both in terms of throughput and allocations. We can refer to this phase as the serializer's "warm-up" phase.

With the type-metadata initialization mode, we shift this runtime metadata generation phase to compile-time, substantially reducing the cost of the first serialization or deserialization procedures. This metadata is generated to the compiling assembly, where it can be initialized and passed directly to JsonSerializer so that it doesn't have to generate it at runtime. This helps reduce the costs of the first serialization or deserialization of each type, alongside other benefits. Note that the serialization-logic mode also eradicates runtime reflection, but in a different way.

We configure this mode for the source generator in a similar way to what's shown above, except that we don't specify features ahead of time, and we change the generation mode:

using System.Text.Json.Serialization;

namespace Test
{
    [JsonSerializable(typeof(JsonMessage), GenerationMode = JsonSourceGenerationMode.Metadata)]
    internal partial class JsonContext : JsonSerializerContext
    {
    }
}

The generator augments the partial context class with the same shape as above. We can then perform serialization using advanced features like reference handling, but still measure and observe performance improvements:

JsonSerializerOptions options = new()
{ 
    ReferenceHander = ReferenceHandler.Preserve,
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};

JsonContext context = new(options);
string json = JsonSerializer.Serialize(jsonMessage, context.JsonMessage);
// {"id":1,"message":"Hello, world!"}

Generating both serialization logic and metadata initialization logic

In some cases, we want the generator to generate both serialization and metadata-initialization logic. For instance, we might only need features compatible with the serialization logic mode on serialization, but also wish to experience some perf improvements on deserialization, including decreased app size after ILLinker trimming.

We'd configure the generator as follows:

using System.Text.Json.Serialization;

namespace Test
{
    [JsonSerializerOptons(
        DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault,
        IgnoreRuntimeCustomConverters = true,
        NamingPolicy = JsonKnownNamingPolicy.BuiltInCamelCase)]
    [JsonSerializable(typeof(JsonMessage), GenerationMode = JsonSourceGenerationMode.MetadataAndSerialization)]
    internal partial class JsonContext : JsonSerializerContext
    {
    }
}

Again, the generated API shape remains the same. We can use the generated source as follows:

// Serializer invokes pre-generated for increased throughput and other benefits.
string json = JsonSerializer.Serialize(jsonMessage, JsonContext.Default.JsonMessage);
// Serializer uses pre-generated type-metadata and avoids warm-up stage for deserialization, alongside other benefits.
JsonMessage message = JsonSerializer.Deserialize(json, JsonContext.Default.JsonMessage);

How to consume the JSON source generator

You can try out the source generator in preview 5 by using the latest preview bits of the System.Text.Json NuGet package. We are working on a proposal for shipping source generators inbox, starting in .NET 6.0. The implementation will be ready by the time we ship .NET 6.0.

Additional notes

  • Multiple types can be included for source generation via [JsonSerializable] on a derived, partial JsonSerializerContext instance, not just one.
  • The JsonSourceGenerationMode.Serialization mode also supports nested object and collection members, not just primitive types.

@buyaa-n
Copy link
Member

buyaa-n commented Jun 14, 2021

Add platform guard attributes to allow custom guards in Platform Compatibility Analyzer

User story: dotnet/runtime#44922
New Attributes proposal dotnet/runtime#51541
Analyzer update PR dotnet/roslyn-analyzers#5087

The CA1416 Platform Compatibility analyzer already recognizes platform guards using the methods in OperatingSystem/RuntimeInformation, such as OperatingSystem.IsWindows and OperatingSystem.IsWindowsVersionAtLeast. However, the analyzer does not recognize any other guard possibilities like the platform check result cached in a field or property, or complex platform check logic is defined in a helper method.

For allowing custom guard possibilities we added new attributes SupportedOSPlatformGuard and UnsupportedOSPlatformGuard for annotating the custom guard members with the corresponding platform name and/or version. Then this annotation is recognized and respected by the Platform Compatibility analyzer's flow analysis logic.

Usage Examples

    [UnsupportedOSPlatformGuard("browser")] // The platform guard attribute
#if TARGET_BROWSER
    internal bool IsSupported => false;
#else
    internal bool IsSupported => true;
#endif

    [UnsupportedOSPlatform("browser")]
    void ApiNotSupportedOnBrowser() { }

    void M1()
    {
        ApiNotSupportedOnBrowser();  // Warns: This call site is reachable on all platforms.'ApiNotSupportedOnBrowser()' is unsupported on: 'browser'

        if (IsSupported)
        {
            ApiNotSupportedOnBrowser();  // Not warn
        }
    }

    [SupportedOSPlatform("Windows")]
    [SupportedOSPlatform("Linux")]
    void ApiOnlyWorkOnWindowsLinux() { }

    [SupportedOSPlatformGuard("Linux")]
    [SupportedOSPlatformGuard("Windows")]
    private readonly bool _isWindowOrLinux = OperatingSystem.IsLinux() || OperatingSystem.IsWindows();

    void M2()
    {
        ApiOnlyWorkOnWindowsLinux();  // This call site is reachable on all platforms.'ApiOnlyWorkOnWindowsLinux()' is only supported on: 'Linux', 'Windows'.

        if (_isWindowOrLinux)
        {
            ApiOnlyWorkOnWindowsLinux();  // Not warn
        }
    }
}

@iMonZ
Copy link

iMonZ commented Jun 15, 2021

its released?

@richlander
Copy link
Member

No. It was supposed to release today. We're hoping for Thursday.

@iMonZ

This comment has been minimized.

@Varorbc

This comment has been minimized.

@iMonZ

This comment has been minimized.

@John0King
Copy link

John0King commented Jul 9, 2021

I'm confusing of how to diagnostics in .net any more .
there are

  • EventSource and EventListener
  • DiagnosticListener and DiagnosticSource

and now there is a new InstrumentListener and MeterListener,

what should be use for libraries ?
should we use them all ? shouldn't here is a standard and powerful api for we to use , and other collectors consume this standard source , and publish/transform to their own format ?

@tarekgh
Copy link
Member

tarekgh commented Jul 9, 2021

@John0King there is docs https://docs.microsoft.com/en-us/dotnet/core/diagnostics/ which is helpful to understand which class to use in which scenario.

and now there is a new InstrumentListener and MeterListener,

Where are you seeing InstrumentListener?
For MeterListener, we started to support the OpenTelemetry Metrics. You can read more there to get the idea.

@John0King
Copy link

John0King commented Jul 9, 2021

@tarekgh The library or framework must write code to support those "check points", and now there have 3 choice:

  1. use EventSource
  2. use EventCounter
  3. use DiagnosticSource
  4. use this new Meter
  5. use logging

the problem is that you are not asking the library author to use them all right ? and this is what I confusing !
I expect there is a standard api I can use instead of write all method above in the library.

for example:

// just a example , don't take it seriously
public async Task LibraryDoSomething()
{
    using(Tracing.Begin("MyLibaray.Key"))
   {
     await doTheWorkAsync();
   }
}

there is the information:

  1. what event start (logging).
  2. how many time the event start (counter)
  3. how long the method execute (Metrics)
  4. what event start first and what start after (Linktrace, if the child method tracking it's own event)

and EventCounter is using a listener from this standard api , and publish to it's eventPipe
and opentelemetry using a package that use a listener from this standard api , and publish to opentelemetry server .

and it seem now, that I use EventCounter then DiagnosticListener and MeterListener can not receive any event.
and if I use other one, then the rest of them can not receive any event !!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests