diff --git a/src/ProjectTemplates/Web.ProjectTemplates/WebWorker-CSharp.csproj.in b/src/ProjectTemplates/Web.ProjectTemplates/BlazorWebWorker-CSharp.csproj.in
similarity index 90%
rename from src/ProjectTemplates/Web.ProjectTemplates/WebWorker-CSharp.csproj.in
rename to src/ProjectTemplates/Web.ProjectTemplates/BlazorWebWorker-CSharp.csproj.in
index 9ac781b4d9cc..721dc10d3b1c 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/WebWorker-CSharp.csproj.in
+++ b/src/ProjectTemplates/Web.ProjectTemplates/BlazorWebWorker-CSharp.csproj.in
@@ -4,6 +4,7 @@
${DefaultNetCoreTargetFramework}
enable
enable
+ true
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/Microsoft.DotNet.Web.ProjectTemplates.csproj b/src/ProjectTemplates/Web.ProjectTemplates/Microsoft.DotNet.Web.ProjectTemplates.csproj
index 741f01a3cee9..76e432d80a2d 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/Microsoft.DotNet.Web.ProjectTemplates.csproj
+++ b/src/ProjectTemplates/Web.ProjectTemplates/Microsoft.DotNet.Web.ProjectTemplates.csproj
@@ -64,7 +64,7 @@
-
+
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/dotnetcli.host.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/dotnetcli.host.json
similarity index 100%
rename from src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/dotnetcli.host.json
rename to src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/dotnetcli.host.json
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/ide.host.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/ide.host.json
similarity index 100%
rename from src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/ide.host.json
rename to src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/ide.host.json
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/ide/icon.ico b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/ide/icon.ico
similarity index 100%
rename from src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/ide/icon.ico
rename to src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/ide/icon.ico
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.cs.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.cs.json
new file mode 100644
index 000000000000..bf0c9ca06543
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.cs.json
@@ -0,0 +1,10 @@
+{
+ "author": "Microsoft",
+ "name": "Blazor Web Worker",
+ "description": "A project for creating a class library that runs .NET code on a web worker from a Blazor WebAssembly or Blazor Web app.",
+ "symbols/Framework/description": "The target framework for the project.",
+ "symbols/Framework/choices/net11.0/description": "Target net11.0",
+ "symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "postActions/restore/description": "Restore NuGet packages required by this project.",
+ "postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
+}
\ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.de.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.de.json
new file mode 100644
index 000000000000..bf0c9ca06543
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.de.json
@@ -0,0 +1,10 @@
+{
+ "author": "Microsoft",
+ "name": "Blazor Web Worker",
+ "description": "A project for creating a class library that runs .NET code on a web worker from a Blazor WebAssembly or Blazor Web app.",
+ "symbols/Framework/description": "The target framework for the project.",
+ "symbols/Framework/choices/net11.0/description": "Target net11.0",
+ "symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "postActions/restore/description": "Restore NuGet packages required by this project.",
+ "postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
+}
\ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.en.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.en.json
similarity index 82%
rename from src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.en.json
rename to src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.en.json
index 8b69676dc1ee..bf0c9ca06543 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.en.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.en.json
@@ -1,7 +1,7 @@
{
"author": "Microsoft",
- "name": ".NET Web Worker",
- "description": "A project for creating a class library that runs .NET code in a Web Worker.",
+ "name": "Blazor Web Worker",
+ "description": "A project for creating a class library that runs .NET code on a web worker from a Blazor WebAssembly or Blazor Web app.",
"symbols/Framework/description": "The target framework for the project.",
"symbols/Framework/choices/net11.0/description": "Target net11.0",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.es.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.es.json
new file mode 100644
index 000000000000..bf0c9ca06543
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.es.json
@@ -0,0 +1,10 @@
+{
+ "author": "Microsoft",
+ "name": "Blazor Web Worker",
+ "description": "A project for creating a class library that runs .NET code on a web worker from a Blazor WebAssembly or Blazor Web app.",
+ "symbols/Framework/description": "The target framework for the project.",
+ "symbols/Framework/choices/net11.0/description": "Target net11.0",
+ "symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "postActions/restore/description": "Restore NuGet packages required by this project.",
+ "postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
+}
\ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.fr.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.fr.json
new file mode 100644
index 000000000000..bf0c9ca06543
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.fr.json
@@ -0,0 +1,10 @@
+{
+ "author": "Microsoft",
+ "name": "Blazor Web Worker",
+ "description": "A project for creating a class library that runs .NET code on a web worker from a Blazor WebAssembly or Blazor Web app.",
+ "symbols/Framework/description": "The target framework for the project.",
+ "symbols/Framework/choices/net11.0/description": "Target net11.0",
+ "symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "postActions/restore/description": "Restore NuGet packages required by this project.",
+ "postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
+}
\ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.it.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.it.json
new file mode 100644
index 000000000000..bf0c9ca06543
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.it.json
@@ -0,0 +1,10 @@
+{
+ "author": "Microsoft",
+ "name": "Blazor Web Worker",
+ "description": "A project for creating a class library that runs .NET code on a web worker from a Blazor WebAssembly or Blazor Web app.",
+ "symbols/Framework/description": "The target framework for the project.",
+ "symbols/Framework/choices/net11.0/description": "Target net11.0",
+ "symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "postActions/restore/description": "Restore NuGet packages required by this project.",
+ "postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
+}
\ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.ja.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.ja.json
new file mode 100644
index 000000000000..bf0c9ca06543
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.ja.json
@@ -0,0 +1,10 @@
+{
+ "author": "Microsoft",
+ "name": "Blazor Web Worker",
+ "description": "A project for creating a class library that runs .NET code on a web worker from a Blazor WebAssembly or Blazor Web app.",
+ "symbols/Framework/description": "The target framework for the project.",
+ "symbols/Framework/choices/net11.0/description": "Target net11.0",
+ "symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "postActions/restore/description": "Restore NuGet packages required by this project.",
+ "postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
+}
\ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.ko.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.ko.json
new file mode 100644
index 000000000000..bf0c9ca06543
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.ko.json
@@ -0,0 +1,10 @@
+{
+ "author": "Microsoft",
+ "name": "Blazor Web Worker",
+ "description": "A project for creating a class library that runs .NET code on a web worker from a Blazor WebAssembly or Blazor Web app.",
+ "symbols/Framework/description": "The target framework for the project.",
+ "symbols/Framework/choices/net11.0/description": "Target net11.0",
+ "symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "postActions/restore/description": "Restore NuGet packages required by this project.",
+ "postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
+}
\ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.pl.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.pl.json
new file mode 100644
index 000000000000..bf0c9ca06543
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.pl.json
@@ -0,0 +1,10 @@
+{
+ "author": "Microsoft",
+ "name": "Blazor Web Worker",
+ "description": "A project for creating a class library that runs .NET code on a web worker from a Blazor WebAssembly or Blazor Web app.",
+ "symbols/Framework/description": "The target framework for the project.",
+ "symbols/Framework/choices/net11.0/description": "Target net11.0",
+ "symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "postActions/restore/description": "Restore NuGet packages required by this project.",
+ "postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
+}
\ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.pt-BR.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.pt-BR.json
new file mode 100644
index 000000000000..bf0c9ca06543
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.pt-BR.json
@@ -0,0 +1,10 @@
+{
+ "author": "Microsoft",
+ "name": "Blazor Web Worker",
+ "description": "A project for creating a class library that runs .NET code on a web worker from a Blazor WebAssembly or Blazor Web app.",
+ "symbols/Framework/description": "The target framework for the project.",
+ "symbols/Framework/choices/net11.0/description": "Target net11.0",
+ "symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "postActions/restore/description": "Restore NuGet packages required by this project.",
+ "postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
+}
\ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.ru.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.ru.json
new file mode 100644
index 000000000000..bf0c9ca06543
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.ru.json
@@ -0,0 +1,10 @@
+{
+ "author": "Microsoft",
+ "name": "Blazor Web Worker",
+ "description": "A project for creating a class library that runs .NET code on a web worker from a Blazor WebAssembly or Blazor Web app.",
+ "symbols/Framework/description": "The target framework for the project.",
+ "symbols/Framework/choices/net11.0/description": "Target net11.0",
+ "symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "postActions/restore/description": "Restore NuGet packages required by this project.",
+ "postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
+}
\ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.tr.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.tr.json
new file mode 100644
index 000000000000..bf0c9ca06543
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.tr.json
@@ -0,0 +1,10 @@
+{
+ "author": "Microsoft",
+ "name": "Blazor Web Worker",
+ "description": "A project for creating a class library that runs .NET code on a web worker from a Blazor WebAssembly or Blazor Web app.",
+ "symbols/Framework/description": "The target framework for the project.",
+ "symbols/Framework/choices/net11.0/description": "Target net11.0",
+ "symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "postActions/restore/description": "Restore NuGet packages required by this project.",
+ "postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
+}
\ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.zh-Hans.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.zh-Hans.json
new file mode 100644
index 000000000000..bf0c9ca06543
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.zh-Hans.json
@@ -0,0 +1,10 @@
+{
+ "author": "Microsoft",
+ "name": "Blazor Web Worker",
+ "description": "A project for creating a class library that runs .NET code on a web worker from a Blazor WebAssembly or Blazor Web app.",
+ "symbols/Framework/description": "The target framework for the project.",
+ "symbols/Framework/choices/net11.0/description": "Target net11.0",
+ "symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "postActions/restore/description": "Restore NuGet packages required by this project.",
+ "postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
+}
\ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.zh-Hant.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.zh-Hant.json
new file mode 100644
index 000000000000..bf0c9ca06543
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/localize/templatestrings.zh-Hant.json
@@ -0,0 +1,10 @@
+{
+ "author": "Microsoft",
+ "name": "Blazor Web Worker",
+ "description": "A project for creating a class library that runs .NET code on a web worker from a Blazor WebAssembly or Blazor Web app.",
+ "symbols/Framework/description": "The target framework for the project.",
+ "symbols/Framework/choices/net11.0/description": "Target net11.0",
+ "symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "postActions/restore/description": "Restore NuGet packages required by this project.",
+ "postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
+}
\ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/template.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/template.json
similarity index 84%
rename from src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/template.json
rename to src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/template.json
index 422f1dbc7bfe..e08fcff957b9 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/template.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/template.json
@@ -3,17 +3,18 @@
"author": "Microsoft",
"classifications": [
"Web",
+ "Blazor",
"WebAssembly",
"Worker",
"Library"
],
- "name": ".NET Web Worker",
+ "name": "Blazor Web Worker",
"generatorVersions": "[1.0.0.0-*)",
- "description": "A project for creating a class library that runs .NET code in a Web Worker.",
- "groupIdentity": "Microsoft.Web.Worker",
+ "description": "A project for creating a class library that runs .NET code on a web worker from a Blazor WebAssembly or Blazor Web app.",
+ "groupIdentity": "Microsoft.Web.Blazor.WebWorker",
"precedence": "10000",
- "identity": "Microsoft.Web.Worker.Library.CSharp.10.0",
- "shortName": "webworker",
+ "identity": "Microsoft.Web.Blazor.WebWorker.Library.CSharp.11.0",
+ "shortName": "blazorwebworker",
"tags": {
"language": "C#",
"type": "project"
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/templatestrings.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/templatestrings.json
similarity index 79%
rename from src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/templatestrings.json
rename to src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/templatestrings.json
index c771640814c8..438554342219 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/templatestrings.json
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/.template.config/templatestrings.json
@@ -1,7 +1,7 @@
{
"author": "Microsoft",
- "name": ".NET Web Worker",
- "description": "A project for creating a class library that runs .NET code in a WebWorker, keeping your WebAssembly UI responsive during heavy computations.",
+ "name": "Blazor Web Worker",
+ "description": "A project for creating a class library that runs .NET code on a web worker from a Blazor WebAssembly or Blazor Web app.",
"symbols/Framework/description": "The target framework for the project.",
"symbols/Framework/choices/0/description": "Target net11.0",
"symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/WebWorkerClient.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/WebWorkerClient.cs
new file mode 100644
index 000000000000..6a3b1e107f89
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/WebWorkerClient.cs
@@ -0,0 +1,48 @@
+using Microsoft.JSInterop;
+
+namespace Company.WebWorker1;
+
+public sealed class WebWorkerClient(IJSObjectReference worker) : IAsyncDisposable
+{
+ private const int DefaultTimeoutMs = 60000;
+ private static readonly string DefaultAssemblyName = typeof(WebWorkerClient).Assembly.GetName().Name!;
+
+ public static async Task CreateAsync(IJSRuntime jsRuntime, int timeoutMs = DefaultTimeoutMs, string? assemblyName = null, CancellationToken cancellationToken = default)
+ {
+ await using var module = await jsRuntime.InvokeAsync(
+ "import", cancellationToken, "./_content/Company.WebWorker1/dotnet-web-worker-client.js");
+
+ var resolvedName = assemblyName ?? DefaultAssemblyName;
+ var options = new { assemblyName = resolvedName };
+ var workerRef = await module.InvokeAsync("create", cancellationToken, timeoutMs, options);
+
+ return new WebWorkerClient(workerRef);
+ }
+
+ // Invokes a [JSExport] method from the web worker.
+ // The method string is the fully qualified path: "AssemblyName.ClassName.MethodName".
+ // Arguments and return values must be primitive types or strings.
+ public async Task InvokeAsync(string method, object[] args, int timeoutMs = DefaultTimeoutMs, CancellationToken cancellationToken = default)
+ {
+ return await worker.InvokeAsync("invoke", cancellationToken, [method, args, timeoutMs]);
+ }
+
+ public async Task InvokeVoidAsync(string method, object[] args, int timeoutMs = DefaultTimeoutMs, CancellationToken cancellationToken = default)
+ {
+ await worker.InvokeVoidAsync("invoke", cancellationToken, [method, args, timeoutMs]);
+ }
+
+ public async ValueTask DisposeAsync()
+ {
+ try
+ {
+ await worker.InvokeVoidAsync("terminate");
+ }
+ catch (JSDisconnectedException)
+ {
+ // JS interop disconnected, worker is already gone
+ }
+
+ await worker.DisposeAsync();
+ }
+}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/WorkerMethods.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/WorkerMethods.cs
new file mode 100644
index 000000000000..171b27758027
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/WorkerMethods.cs
@@ -0,0 +1,15 @@
+using System.Runtime.InteropServices.JavaScript;
+using System.Runtime.Versioning;
+
+namespace Company.WebWorker1;
+
+// Define [JSExport] methods here to run them in a Web Worker.
+// Call them from your Blazor app using WebWorkerClient.InvokeAsync.
+// Example: await worker.InvokeAsync("Company.WebWorker1.WorkerMethods.Greet", ["World"]);
+
+[SupportedOSPlatform("browser")]
+public static partial class WorkerMethods
+{
+ [JSExport]
+ public static string Greet(string name) => $"Hello, {name}!";
+}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/wwwroot/dotnet-web-worker-client.js b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/wwwroot/dotnet-web-worker-client.js
similarity index 55%
rename from src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/wwwroot/dotnet-web-worker-client.js
rename to src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/wwwroot/dotnet-web-worker-client.js
index c3f9ceba738e..94ca9127ed8b 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/wwwroot/dotnet-web-worker-client.js
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/wwwroot/dotnet-web-worker-client.js
@@ -1,5 +1,8 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
+function withTimeout(promise, timeoutMs, timeoutMessage) {
+ const timeout = new Promise((_, reject) =>
+ setTimeout(() => reject(new Error(timeoutMessage)), timeoutMs));
+ return Promise.race([promise, timeout]);
+}
class DotnetWebWorkerClient {
#worker;
@@ -10,29 +13,31 @@ class DotnetWebWorkerClient {
this.#worker = worker;
}
- static create() {
- return new Promise((resolve, reject) => {
- const worker = new Worker('_content/Company.WebWorker1/dotnet-web-worker.js', { type: "module" });
-
- worker.addEventListener('error', (e) => {
- reject(new Error(e.message || 'Worker encountered an error'));
- });
+ static create(initTimeoutMs, options = {}) {
+ const worker = new Worker('_content/Company.WebWorker1/dotnet-web-worker.js', { type: "module" });
+ const initWorker = new Promise((resolve, reject) => {
+ worker.addEventListener('error', (e) =>
+ reject(new Error(e.message || 'Worker encountered an error')));
worker.addEventListener('message', function onMessage(e) {
if (e.data.type === "ready") {
worker.removeEventListener('message', onMessage);
- if (e.data.error) {
- reject(new Error(e.data.error));
- } else {
- const client = new DotnetWebWorkerClient(worker);
- client.#setupMessageHandler();
- resolve(client);
- }
+ e.data.error ? reject(new Error(e.data.error)) : resolve();
}
});
+ });
+
+ const dotnetJsUrl = DotnetWebWorkerClient.#resolveDotnetJsUrl();
+ const assemblyName = options?.assemblyName ?? null;
+ worker.postMessage({ type: 'init', dotnetJsUrl, assemblyName });
- const dotnetJsUrl = DotnetWebWorkerClient.#resolveDotnetJsUrl();
- worker.postMessage({ type: 'init', dotnetJsUrl });
+ return withTimeout(initWorker, initTimeoutMs, 'Worker initialization timed out').then(() => {
+ const client = new DotnetWebWorkerClient(worker);
+ client.#setupMessageHandler();
+ return client;
+ }, err => {
+ worker.terminate();
+ throw err;
});
}
@@ -43,23 +48,20 @@ class DotnetWebWorkerClient {
return import.meta.resolve?.(dotnetJsUrl) ?? dotnetJsUrl;
}
- invoke(method, args) {
- return new Promise((resolve, reject) => {
+ invoke(method, args, timeoutMs) {
+ const invoke = new Promise((resolve, reject) => {
const id = ++this.#requestId;
- this.#pendingRequests[id] = { resolve: r => resolve(this.#parseIfJson(r)), reject };
+ this.#pendingRequests[id] = { resolve, reject };
this.#worker.postMessage({ method, args, requestId: id });
});
- }
- #parseIfJson(value) {
- if (typeof value === 'string') {
- try {
- return JSON.parse(value);
- } catch {
- // not JSON, return as-is
+ return withTimeout(invoke, timeoutMs, `Worker method '${method}' timed out`).catch(err => {
+ const id = this.#requestId;
+ if (this.#pendingRequests[id]) {
+ delete this.#pendingRequests[id];
}
- }
- return value;
+ throw err;
+ });
}
terminate() {
@@ -96,6 +98,6 @@ class DotnetWebWorkerClient {
}
}
-export function create() {
- return DotnetWebWorkerClient.create();
+export function create(initTimeoutMs, options) {
+ return DotnetWebWorkerClient.create(initTimeoutMs, options);
}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/wwwroot/dotnet-web-worker.js b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/wwwroot/dotnet-web-worker.js
similarity index 72%
rename from src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/wwwroot/dotnet-web-worker.js
rename to src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/wwwroot/dotnet-web-worker.js
index f5fe5896c041..336613184362 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/wwwroot/dotnet-web-worker.js
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWebWorker-CSharp/wwwroot/dotnet-web-worker.js
@@ -1,15 +1,18 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-let workerExports = null;
+let workerExports = {};
let startupError = null;
-async function initialize(dotnetJsUrl) {
+async function initialize(dotnetJsUrl, assemblyName) {
try {
const { dotnet } = await import(dotnetJsUrl);
const { getAssemblyExports, getConfig } = await dotnet.create();
- const assemblyName = getConfig().mainAssemblyName;
- workerExports = await getAssemblyExports(assemblyName);
+ const mainAssemblyName = getConfig().mainAssemblyName;
+
+ workerExports = { ...await getAssemblyExports(mainAssemblyName) };
+
+ if (assemblyName && assemblyName !== mainAssemblyName) {
+ workerExports = { ...workerExports, ...await getAssemblyExports(assemblyName) };
+ }
+
self.postMessage({ type: "ready" });
} catch (err) {
const errorMessage = err?.message ?? String(err);
@@ -21,14 +24,14 @@ async function initialize(dotnetJsUrl) {
self.addEventListener('message', async (e) => {
if (e.data.type === 'init') {
- await initialize(e.data.dotnetJsUrl);
+ await initialize(e.data.dotnetJsUrl, e.data.assemblyName);
return;
}
const { method, args, requestId } = e.data;
try {
- if (!workerExports) {
+ if (Object.keys(workerExports).length === 0) {
throw new Error(startupError || "Worker .NET runtime not loaded");
}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.cs.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.cs.json
deleted file mode 100644
index 7da3ea360b4a..000000000000
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.cs.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "author": "Microsoft",
- "name": "Webový pracovní proces .NET",
- "description": "Projekt pro vytvoření knihovny tříd, která spouští kód .NET ve webovém pracovním procesu",
- "symbols/Framework/description": "Cílová architektura pro projekt.",
- "symbols/Framework/choices/net11.0/description": "Cílový net11.0",
- "symbols/skipRestore/description": "Je-li zadáno, při vytvoření přeskočí automatické obnovení projektu.",
- "postActions/restore/description": "Obnovte balíčky NuGet vyžadované tímto projektem.",
- "postActions/restore/manualInstructions/default/text": "Spustit „dotnet restore“"
-}
\ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.de.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.de.json
deleted file mode 100644
index 001483cba952..000000000000
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.de.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "author": "Microsoft",
- "name": ".NET-Worker",
- "description": "Ein Projekt zur Erstellung einer Klassenbibliothek, die .NET-Code in einem Worker ausführt.",
- "symbols/Framework/description": "Das Zielframework für das Projekt.",
- "symbols/Framework/choices/net11.0/description": "Ziel net11.0",
- "symbols/skipRestore/description": "Wenn angegeben, wird die automatische Wiederherstellung des Projekts beim Erstellen übersprungen.",
- "postActions/restore/description": "Stellt die NuGet-Pakete wieder her, die für dieses Projekt erforderlich sind.",
- "postActions/restore/manualInstructions/default/text": "„dotnet restore“ ausführen"
-}
\ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.es.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.es.json
deleted file mode 100644
index ef913b6dbd55..000000000000
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.es.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "author": "Microsoft",
- "name": "Trabajo web de .NET",
- "description": "Proyecto para crear una biblioteca de clases que ejecuta código .NET en un trabajo web.",
- "symbols/Framework/description": "Marco de destino del proyecto.",
- "symbols/Framework/choices/net11.0/description": "Net11.0 de destino",
- "symbols/skipRestore/description": "Si se especifica, se omite la restauración automática del proyecto durante la creación.",
- "postActions/restore/description": "Restaure los paquetes NuGet necesarios para este proyecto.",
- "postActions/restore/manualInstructions/default/text": "Ejecutar \"dotnet restore\""
-}
\ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.fr.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.fr.json
deleted file mode 100644
index 00bcdd667b15..000000000000
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.fr.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "author": "Microsoft",
- "name": "Worker .NET",
- "description": "Un projet de création d’une bibliothèque de classes qui exécute du code .NET dans un Web Worker.",
- "symbols/Framework/description": "Infrastructure cible du projet.",
- "symbols/Framework/choices/net11.0/description": "Net11.0 cible",
- "symbols/skipRestore/description": "Si spécifié, ignore la restauration automatique du projet lors de la création.",
- "postActions/restore/description": "Restaurer les packages NuGet requis par ce projet.",
- "postActions/restore/manualInstructions/default/text": "Exécuter 'dotnet restore'"
-}
\ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.it.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.it.json
deleted file mode 100644
index dbb5c17ddb4b..000000000000
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.it.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "author": "Microsoft",
- "name": "Ruolo di lavoro .NET",
- "description": "Progetto per creare una libreria di classi che esegue il codice .NET in un ruolo di lavoro.",
- "symbols/Framework/description": "Framework di destinazione per il progetto.",
- "symbols/Framework/choices/net11.0/description": "Destinazione net11.0",
- "symbols/skipRestore/description": "Se specificato, ignora il ripristino automatico del progetto durante la creazione.",
- "postActions/restore/description": "Consente di ripristinare i pacchetti NuGet richiesti da questo progetto.",
- "postActions/restore/manualInstructions/default/text": "Esegui \"dotnet restore\""
-}
\ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.ja.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.ja.json
deleted file mode 100644
index 291e3470ca22..000000000000
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.ja.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "author": "Microsoft",
- "name": ".NET Web Worker",
- "description": "Web worker で .NET コードを実行するクラス ライブラリを作成するためのプロジェクト。",
- "symbols/Framework/description": "プロジェクトのターゲット フレームワーク。",
- "symbols/Framework/choices/net11.0/description": "ターゲット net11.0",
- "symbols/skipRestore/description": "指定した場合、作成時にプロジェクトの自動復元がスキップされます。",
- "postActions/restore/description": "このプロジェクトに必要な NuGet パッケージを復元します。",
- "postActions/restore/manualInstructions/default/text": "'dotnet restore' を実行する"
-}
\ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.ko.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.ko.json
deleted file mode 100644
index a5c2aaba5ec0..000000000000
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.ko.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "author": "Microsoft",
- "name": ".NET 웹 작업자",
- "description": "웹 작업자에서 .NET 코드를 실행하는 클래스 라이브러리를 만드는 프로젝트입니다.",
- "symbols/Framework/description": "프로젝트에 대한 대상 프레임워크입니다.",
- "symbols/Framework/choices/net11.0/description": "Target net11.0",
- "symbols/skipRestore/description": "지정된 경우, 프로젝트 생성 시 자동 복원을 건너뜁니다.",
- "postActions/restore/description": "이 프로젝트에 필요한 NuGet 패키지를 복원합니다.",
- "postActions/restore/manualInstructions/default/text": "'dotnet restore' 실행"
-}
\ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.pl.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.pl.json
deleted file mode 100644
index 11025e02d651..000000000000
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.pl.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "author": "Microsoft",
- "name": "Internetowy proces roboczy środowiska .NET",
- "description": "Projekt służący do tworzenia biblioteki klas, która uruchamia kod środowiska .NET w internetowym procesie roboczym.",
- "symbols/Framework/description": "Platforma docelowa dla tego projektu.",
- "symbols/Framework/choices/net11.0/description": "Docelowa platforma net11.0",
- "symbols/skipRestore/description": "Jeśli ta opcja jest określona, pomija automatyczne przywracanie projektu podczas tworzenia.",
- "postActions/restore/description": "Przywróć pakiety NuGet wymagane przez ten projekt.",
- "postActions/restore/manualInstructions/default/text": "Uruchom polecenie „dotnet restore”"
-}
\ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.pt-BR.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.pt-BR.json
deleted file mode 100644
index ab9de13b3d25..000000000000
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.pt-BR.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "author": "Microsoft",
- "name": "Trabalho .NET",
- "description": "Um projeto para criar uma biblioteca de classes que executa código .NET em um Trabalho.",
- "symbols/Framework/description": "A estrutura de destino para o projeto.",
- "symbols/Framework/choices/net11.0/description": "Net11.0 de destino",
- "symbols/skipRestore/description": "Se especificado, ignora a restauração automática do projeto que está sendo criado.",
- "postActions/restore/description": "Restaurar os pacotes NuGet exigidos por esse projeto.",
- "postActions/restore/manualInstructions/default/text": "Execute 'dotnet restore'"
-}
\ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.ru.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.ru.json
deleted file mode 100644
index 08f9f746b0ed..000000000000
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.ru.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "author": "Майкрософт",
- "name": "Рабочая роль .NET",
- "description": "Проект по созданию библиотеки классов, которая выполняет код .NET в рабочей роли.",
- "symbols/Framework/description": "Целевая платформа для проекта.",
- "symbols/Framework/choices/net11.0/description": "Цель net11.0",
- "symbols/skipRestore/description": "Если указано, пропускает автоматическое восстановление проекта при создании.",
- "postActions/restore/description": "Восстановление пакетов NuGet, необходимых для этого проекта.",
- "postActions/restore/manualInstructions/default/text": "Выполнить команду \"dotnet restore\""
-}
\ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.tr.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.tr.json
deleted file mode 100644
index 181be5bce10f..000000000000
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.tr.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "author": "Microsoft",
- "name": ".NET Web Çalışanı",
- "description": "Web Çalışanı içinde .NET kodunu çalıştıran bir sınıf kitaplığı oluşturma projesi.",
- "symbols/Framework/description": "Projenin hedef çerçevesi.",
- "symbols/Framework/choices/net11.0/description": "Hedef net11.0",
- "symbols/skipRestore/description": "Belirtilmişse oluştururken projenin otomatik geri yüklenmesini atlar.",
- "postActions/restore/description": "Bu projenin gerektirdiği NuGet paketlerini geri yükleyin.",
- "postActions/restore/manualInstructions/default/text": "\"dotnet restore\" komutunu çalıştır"
-}
\ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.zh-Hans.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.zh-Hans.json
deleted file mode 100644
index 6ed8a246802f..000000000000
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.zh-Hans.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "author": "Microsoft",
- "name": ".NET 辅助角色",
- "description": "用于创建在辅助角色中运行 .NET 代码的类库的项目。",
- "symbols/Framework/description": "项目的目标框架。",
- "symbols/Framework/choices/net11.0/description": "目标 net11.0",
- "symbols/skipRestore/description": "如果已指定,则在创建时跳过项目的自动还原。",
- "postActions/restore/description": "还原此项目所需的 NuGet 包。",
- "postActions/restore/manualInstructions/default/text": "运行 \"dotnet restore\""
-}
\ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.zh-Hant.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.zh-Hant.json
deleted file mode 100644
index 62086db0d1ef..000000000000
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/.template.config/localize/templatestrings.zh-Hant.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "author": "Microsoft",
- "name": ".NET 背景工作角色",
- "description": "用於建立類別庫的專案,可在背景工作角色中執行 .NET 程式碼。",
- "symbols/Framework/description": "專案的目標架構。",
- "symbols/Framework/choices/net11.0/description": "目標 net11.0",
- "symbols/skipRestore/description": "如果指定,則會在建立時跳過專案的自動還原。",
- "postActions/restore/description": "還原此專案所需的 NuGet 套件。",
- "postActions/restore/manualInstructions/default/text": "執行 'dotnet restore'"
-}
\ No newline at end of file
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/WebWorkerClient.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/WebWorkerClient.cs
deleted file mode 100644
index a02d26ca7dbc..000000000000
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebWorker-CSharp/WebWorkerClient.cs
+++ /dev/null
@@ -1,106 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using Microsoft.JSInterop;
-
-namespace Company.WebWorker1;
-
-///
-/// Client for communicating with a Web Worker running .NET code.
-///
-///
-///
-/// Worker methods are static methods marked with [JSExport] in a static partial class.
-/// By default, they should be defined in the main application. The assembly name in
-/// dotnet-web-worker.js must match the assembly containing the worker methods.
-/// The project requires <AllowUnsafeBlocks>true</AllowUnsafeBlocks> in the .csproj file.
-///
-///
-/// Due to [JSExport] limitations, worker methods can only return primitives or strings.
-/// For complex types, serialize to JSON before returning—it will be automatically deserialized.
-///
-///
-/// Example worker class (add this to your main app):
-///
-/// [SupportedOSPlatform("browser")]
-/// public static partial class MyWorker
-/// {
-/// [JSExport]
-/// public static string Process(string input) => $"Processed: {input}";
-/// }
-///
-///
-///
-/// Example usage:
-///
-/// @inject IJSRuntime JSRuntime
-///
-/// private WebWorkerClient? _worker;
-///
-/// protected override async Task OnAfterRenderAsync(bool firstRender)
-/// {
-/// if (firstRender)
-/// {
-/// _worker = await WebWorkerClient.CreateAsync(JSRuntime);
-/// }
-/// }
-///
-/// async Task CallWorker()
-/// {
-/// var result = await _worker!.InvokeAsync<string>("MyApp.MyWorker.Process", ["Hello"]);
-/// }
-///
-/// public async ValueTask DisposeAsync() => await (_worker?.DisposeAsync() ?? ValueTask.CompletedTask);
-///
-///
-///
-public sealed class WebWorkerClient(IJSObjectReference worker) : IAsyncDisposable
-{
- ///
- /// Creates and initializes a new .NET Web Worker client instance.
- ///
- /// The JS runtime instance.
- /// A ready-to-use WebWorkerClient instance.
- /// Thrown if the worker fails to initialize.
- public static async Task CreateAsync(IJSRuntime jsRuntime)
- {
- await using var module = await jsRuntime.InvokeAsync(
- "import", "./_content/Company.WebWorker1/dotnet-web-worker-client.js");
-
- var workerRef = await module.InvokeAsync("create");
-
- return new WebWorkerClient(workerRef);
- }
-
- ///
- /// Invokes a method on the worker and returns the result.
- ///
- /// The type of the result.
- /// Full method path: "Namespace.ClassName.MethodName"
- /// Arguments to pass to the method.
- /// Token to cancel the operation.
- /// The result from the worker method.
- /// Thrown if the operation is canceled.
- /// Thrown if the worker method throws an exception.
- public async Task InvokeAsync(string method, object[] args, CancellationToken cancellationToken = default)
- {
- return await worker.InvokeAsync("invoke", cancellationToken, [method, args]);
- }
-
- ///
- /// Terminates the worker and releases resources.
- ///
- public async ValueTask DisposeAsync()
- {
- try
- {
- await worker.InvokeVoidAsync("terminate");
- }
- catch (JSDisconnectedException)
- {
- // Circuit disconnected, worker is already gone
- }
-
- await worker.DisposeAsync();
- }
-}
diff --git a/src/ProjectTemplates/test/Templates.Blazor.Tests/WebWorkerTemplateE2ETest.cs b/src/ProjectTemplates/test/Templates.Blazor.Tests/WebWorkerTemplateE2ETest.cs
index bd0f5e0c2d42..59d74bd12b3c 100644
--- a/src/ProjectTemplates/test/Templates.Blazor.Tests/WebWorkerTemplateE2ETest.cs
+++ b/src/ProjectTemplates/test/Templates.Blazor.Tests/WebWorkerTemplateE2ETest.cs
@@ -160,31 +160,17 @@ public async ValueTask DisposeAsync()
private async Task CreateWebWorkerLibrary(string workerLibDir)
{
var hiveArg = $"--debug:disable-sdk-templates --debug:custom-hive \"{TemplatePackageInstaller.CustomHivePath}\"";
- var args = $"new webworker {hiveArg} -n WorkerLib -o \"{workerLibDir}\"";
+ var args = $"new blazorwebworker {hiveArg} -n WorkerLib -o \"{workerLibDir}\"";
using var result = ProcessEx.Run(Output, AppContext.BaseDirectory, DotNetMuxer.MuxerPathOrDefault(), args);
await result.Exited;
- Assert.True(result.ExitCode == 0, $"Failed to create webworker template: {result.Output}\n{result.Error}");
+ Assert.True(result.ExitCode == 0, $"Failed to create blazorwebworker template: {result.Output}\n{result.Error}");
- ModifyWorkerLibProjectFile(workerLibDir);
+ CopyWorkerMethods(workerLibDir);
- using var restoreResult = ProcessEx.Run(Output, workerLibDir, DotNetMuxer.MuxerPathOrDefault(), "restore");
+ using var restoreResult= ProcessEx.Run(Output, workerLibDir, DotNetMuxer.MuxerPathOrDefault(), "restore");
await restoreResult.Exited;
- Assert.True(restoreResult.ExitCode == 0, $"Failed to restore webworker library: {restoreResult.Output}\n{restoreResult.Error}");
- }
-
- private static void ModifyWorkerLibProjectFile(string workerLibDir)
- {
- var csprojPath = Path.Combine(workerLibDir, "WorkerLib.csproj");
- var content = File.ReadAllText(csprojPath);
-
- if (!content.Contains("AllowUnsafeBlocks"))
- {
- content = content.Replace(
- "",
- " true\n ");
- File.WriteAllText(csprojPath, content);
- }
+ Assert.True(restoreResult.ExitCode == 0, $"Failed to restore blazorwebworker library: {restoreResult.Output}\n{restoreResult.Error}");
}
private static void AddHostProjectSettings(Project hostProject)
@@ -194,13 +180,8 @@ private static void AddHostProjectSettings(Project hostProject)
var settings = @"
- true
true
-
-
-
-
";
content = content.Replace("", settings + "");
File.WriteAllText(csprojPath, content);
@@ -230,9 +211,12 @@ private void CopyTestAssets(Project hostProject)
File.WriteAllText(
Path.Combine(pagesDir, "WebWorkerTest.razor"),
testComponentContent);
+ }
+ private static void CopyWorkerMethods(string workerLibDir)
+ {
var workerMethodsSource = Path.Combine(TestAssetsPath, "TestWorkerMethods.cs");
- File.Copy(workerMethodsSource, Path.Combine(hostProject.TemplateOutputDir, "TestWorkerMethods.cs"), overwrite: true);
+ File.Copy(workerMethodsSource, Path.Combine(workerLibDir, "TestWorkerMethods.cs"), overwrite: true);
}
private void LogBuildDiagnostics(Project hostProject, string buildKind)
diff --git a/src/ProjectTemplates/test/Templates.Tests/WebWorkerTemplateTest.cs b/src/ProjectTemplates/test/Templates.Tests/WebWorkerTemplateTest.cs
index 0b2b82586e7d..942a730adbd6 100644
--- a/src/ProjectTemplates/test/Templates.Tests/WebWorkerTemplateTest.cs
+++ b/src/ProjectTemplates/test/Templates.Tests/WebWorkerTemplateTest.cs
@@ -38,7 +38,7 @@ public async Task WebWorkerTemplate_CanCreateBuildPublish()
{
var project = await ProjectFactory.CreateProject(Output);
- await project.RunDotNetNewAsync("webworker");
+ await project.RunDotNetNewAsync("blazorwebworker");
await project.RunDotNetPublishAsync();
diff --git a/src/ProjectTemplates/test/Templates.Tests/template-baselines.json b/src/ProjectTemplates/test/Templates.Tests/template-baselines.json
index 452fabb4a9b0..2fa9e721895a 100644
--- a/src/ProjectTemplates/test/Templates.Tests/template-baselines.json
+++ b/src/ProjectTemplates/test/Templates.Tests/template-baselines.json
@@ -3745,12 +3745,13 @@
]
}
},
- "webworker": {
+ "blazorwebworker": {
"Default": {
- "Template": "webworker",
- "Arguments": "new webworker",
+ "Template": "blazorwebworker",
+ "Arguments": "new blazorwebworker",
"Files": [
"WebWorkerClient.cs",
+ "WorkerMethods.cs",
"wwwroot/dotnet-web-worker.js",
"wwwroot/dotnet-web-worker-client.js"
]