core
core copied to clipboard
What's new in .NET 7 RC 2
What's new in .NET 7 RC 2
This issue is for teams to highlight work for the community that will release .NET 7 RC 2
To add content, use a new conversation entry. The entry should include the team name and feature title as the first line 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: https://github.com/dotnet/core/issues/7106 Preview 2: https://github.com/dotnet/core/issues/7107 Preview 3: https://github.com/dotnet/core/issues/7108 Preview 4: https://github.com/dotnet/core/issues/7378 Preview 5: https://github.com/dotnet/core/issues/7441 Preview 6: https://github.com/dotnet/core/issues/7454 Preview 7: https://github.com/dotnet/core/issues/7455 RC 1: https://github.com/dotnet/core/issues/7716 RC 2: https://github.com/dotnet/core/issues/7717
wasm-experimental: Experimental support for WebAssembly multithreading
https://github.com/dotnet/runtime/issues/68162
The wasm-experimental workload supports multi-threaded .NET apps using JavaScript Web Workers. This support is only implemented for the wasmbrowser template, Blazor apps do not support threading at this time.
Threaded WebAssembly support is experimental in .NET 7 and this is an opportunity for you to provide early feedback on the feature for a future release of .NET.
-
To get started, install .NET 7 RC2 and the
wasm-experimentalworkload:dotnet workload install wasm-experimental -
Create a new
wasmbrowserapp:dotnet new wasmbrowser -
The full example below is available at https://github.com/lambdageek/hithread
-
To enable threading, add the
WasmEnableThreadsproperty to the project file:<PropertyGroup> <WasmEnableThreads>true</WasmEnableThreads> </PropertyGroup> -
Optionally if you use platform-guard attributes like
SupportedOSPlatform/UnsupportedOSPlatformin your code, add the .NET 7 package feed to yourNuGet.configand add a reference to the threading package:<!-- in NuGet.config --> <configuration> <packageSources> <add key="dotnet7" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet7/nuget/v3/index.json" /> </packageSources> </configuration><!-- your .csproj --> <ItemGroup> <PackageReference Include="Microsoft.NET.WebAssembly.Threading" Version="7.0.0-rc.2.*" /> </ItemGroup> -
Create and run a new thread.
using System; using System.Threading; using System.Runtime.Versioning; using System.Runtime.InteropServices.JavaScript; [assembly:SupportedOSPlatform("browser")] new Thread(SecondThread).Start(); Console.WriteLine($"Hello, Browser from the main thread {Thread.CurrentThread.ManagedThreadId}"); static void SecondThread() { Console.WriteLine ($"Hello from Thread {Thread.CurrentThread.ManagedThreadId}"); for (int i = 0; i < 5; ++i) { Console.WriteLine ($"Ping {i}"); Thread.Sleep (100); } } -
build the app and run with the .NET app host
dotnet build dotnet runor publish and serve the app with another static server such as dotnet-serve. Note that cross origin isolation must be enabled by serving the COOP and COEP headers
dotnet publish -c Release dotnet serve -h "Cross-Origin-Opener-Policy:same-origin" -h "Cross-Origin-Embedder-Policy:require-corp" --directory bin/Release/net7.0/browser-wasm/AppBundle/ -
Open the served URL in a browser (note: Chrome, Edge or Safari; at this time Firefox is not supported until Mozilla #1540913 is fixed) open developer tools, and the console should include the following output:
Hello from Thread 2 Hello, Browser from the main thread 1 Ping 0 Ping 1 Ping 2 Ping 3 Ping 4 -
Many properties that control the build such as
WasmBuildNative,RunAOTCompilation,WasmEnableSIMD, etc are supported with threading.
Notes and known issues:
JSImportandJSExportwork from the browser thread, only- WebSocket operations are only supported on the main thread
- A
SynchronizationContextis installed on the browser thread by default. If you do not useConfigureAwait(false)when awaiting asynchronous operations, they will be scheduled on the browser thread. Conversely, not usingConfigureAwaitallows your asynchronous operations to return to the browser thread in order to interact with the DOM or other JS libraries that are only available on the main thread. - By default the app will create 4 Web Workers that will be used to execute .NET Threads. The runtime will reuse Web Workers to run multiple .NET threads (that is, after one thread stops, the Worker will be pooled and reused for a subsequent
Thread.Startcall). To control the number of workers that are created at app startup, configure the_WasmPThreadPoolSizeproperty (note the property is experimental and may change in a future release). Note that we build the runtime with the EmscriptenPTHREAD_POOL_SIZE_STRICTset to 2 (see Emscriptensettings.jsdocumentation which means that creating additional workers after the initial pool of workers is exhausted will be a hard error that will stop the app. The maximum parallelism of your app must not exceed the_WasmPThreadPoolSize. Please open an issue in dotnet/runtime if this policy is too restrictive. - Debugging multithreaded WASM is not supported yet
- Threading does not work in Firefox due to Bugzilla #1540913. We currently compile .NET to ES6 modules, which causes Emscripten to use the dynamic
import(uri).then(callback)module import that doesn't work in Web Workers in Firefox.
@ericstj @karelz @jeffhandley @eerhardt for any RC2 stuff
@JeremyLikness @AngelosP FYI
System.Text.Json AppContext switch re-enabling reflection fallback in source generation https://github.com/dotnet/runtime/pull/75615
.NET 7 introduced an intentional breaking change which removes silent fallback to reflection-based serialization in System.Text.Json source generators. Based on early feedback we have been receiving from customers , it appears that quite a few users have (mostly accidentally) taken a dependency on the fallback behavior.
Even though a workaround for the breaking change has been documented, it still requires a code change which might not be possible in certain scenaria. Starting in .NET 7 RC 2, you can re-enable reflection fallback globally using the provided AppContext compatibility switch. Add the following entry to your application's project file to re-enable reflection fallback for all source-generated contexts in your app. For more information on using AppContext switches, see the article on .NET runtime configuration settings.
<ItemGroup>
<RuntimeHostConfigurationOption Include="System.Text.Json.Serialization.EnableSourceGenReflectionFallback" Value="true" />
</ItemGroup>
We have added 2 new analyzers for correct usage of new APIs:
- Implement Generic Math interfaces correctly - Ensures the .NET Generic Math interfaces that uses Curiously Recurring Template Pattern (CRTP) are implemented correctly in user code. In particular it warns if a type that implements the .NET Generic Math interfaces (that implements CRTP pattern) do NOT fill the generic type parameter with the type itself.
Example:
public readonly struct DateOnly : IParsable<DateOnly> // correct implementation of IParsable<TSelf> interface { ... } public readonly struct MyDate : IParsable<DateOnly> // Warns: "The 'IParsable<TSelf>' requires the 'TSelf' type parameter to be filled with the derived type 'MyDate' " the type parameter TSelf { ... } - Prevent behavioral change in built-in operators for IntPtr and UIntPtr - Some built in operators added in .NET 7 for System.IntPtr and System.UIntPtr behave differently than the user defined operators in .NET 6 and below. Some operators that used to throw in unchecked context while overflowing now no longer throw unless wrapped within checked context, and some operators that not used to throw in checked context now would throw when overflow unless wrapped within unchecked context. The analyzer detects the code that could cause those behavioral changes and informs it.
Examples:
checked { intPtr2 = intPtr1 + 2; // Warns: "Starting with .NET 7 the operator '+' will throw when overflowing in a checked context. Wrap the expression with an 'unchecked' statement to restore the .NET 6 behavior." intPtr2 = intPtr1 - 2; // Warns: "Starting with .NET 7 the operator '-' will throw when overflowing in a checked context. Wrap the expression with an 'unchecked' statement to restore the .NET 6 behavior." void* ptr = (void*)intPtr1; // Warns: "Starting with .NET 7 the explicit conversion '(void*)IntPtr' will throw when overflowing in a checked context. Wrap the expression with an 'unchecked' statement to restore the .NET 6 behavior." intPtr2 = (IntPtr)ptr; // Warns: "Starting with .NET 7 the explicit conversion '(IntPtr)void*' will throw when overflowing in a checked context. Wrap the expression with an 'unchecked' statement to restore the .NET 6 behavior." } intPtr1 = (IntPtr)longValue; // Warns: "Starting with .NET 7 the explicit conversion '(IntPtr)Int64' will not throw when overflowing in an unchecked context. Wrap the expression with a 'checked' statement to restore the .NET 6 behavior." int a = (int)intPtr1; // Warns: "Starting with .NET 7 the explicit conversion '(Int32)IntPtr' will not throw when overflowing in an unchecked context. Wrap the expression with a 'checked' statement to restore the .NET 6 behavior."
@JonDouglas I spoke with @lambdageek and the plan is to include the WebAssembly multithreading content in the ASP.NET Core post.
.NET 7 GA is available. Closing these pre-release issues.