From 516f63b695561ebf1488979cf659c9a6a0fcd97f Mon Sep 17 00:00:00 2001 From: KristofferStrube Date: Mon, 8 Jul 2024 19:54:32 +0200 Subject: [PATCH] Made job only begin listening once when constructed. --- .../Pages/PingPong.razor | 50 +++++++++---------- .../IJob.cs | 13 ++++- .../JobWorker.cs | 18 ++++++- .../JsonJob.cs | 25 +++++----- .../TaskJsonJob.cs | 28 ++++++----- 5 files changed, 82 insertions(+), 52 deletions(-) diff --git a/samples/KristofferStrube.Blazor.WebWorkers.WasmExample/Pages/PingPong.razor b/samples/KristofferStrube.Blazor.WebWorkers.WasmExample/Pages/PingPong.razor index 444db7a..ced98b0 100644 --- a/samples/KristofferStrube.Blazor.WebWorkers.WasmExample/Pages/PingPong.razor +++ b/samples/KristofferStrube.Blazor.WebWorkers.WasmExample/Pages/PingPong.razor @@ -27,31 +27,31 @@ public async Task CreatePongWorker() { -SlimWorker slimWorker = await SlimWorker.CreateAsync( - jSRuntime: JSRuntime, - assembly: typeof(AssemblyPongWorker).Assembly.GetName().Name!, - ["Argument1", "Argument2"] -); - -EventListener eventListener = default!; -eventListener = await EventListener.CreateAsync(JSRuntime, async e => -{ - object? data = await e.Data.GetValueAsync(); - switch (data) - { - case "ready": - Log("We are sending a ping!"); - await slimWorker.PostMessageAsync("ping"); - break; - case "pong": - Log("We received a pong!"); - await slimWorker.RemoveOnMessageEventListenerAsync(eventListener); - await eventListener.DisposeAsync(); - await slimWorker.DisposeAsync(); - break; - } -}); -await slimWorker.AddOnMessageEventListenerAsync(eventListener); + SlimWorker slimWorker = await SlimWorker.CreateAsync( + jSRuntime: JSRuntime, + assembly: typeof(AssemblyPongWorker).Assembly.GetName().Name!, + ["Argument1", "Argument2"] + ); + + EventListener eventListener = default!; + eventListener = await EventListener.CreateAsync(JSRuntime, async e => + { + object? data = await e.Data.GetValueAsync(); + switch (data) + { + case "ready": + Log("We are sending a ping!"); + await slimWorker.PostMessageAsync("ping"); + break; + case "pong": + Log("We received a pong!"); + await slimWorker.RemoveOnMessageEventListenerAsync(eventListener); + await eventListener.DisposeAsync(); + await slimWorker.DisposeAsync(); + break; + } + }); + await slimWorker.AddOnMessageEventListenerAsync(eventListener); } private void Log(string message) diff --git a/src/KristofferStrube.Blazor.WebWorkers/IJob.cs b/src/KristofferStrube.Blazor.WebWorkers/IJob.cs index 8229d37..f41e232 100644 --- a/src/KristofferStrube.Blazor.WebWorkers/IJob.cs +++ b/src/KristofferStrube.Blazor.WebWorkers/IJob.cs @@ -1,4 +1,6 @@ -using System.Collections.Concurrent; +using KristofferStrube.Blazor.DOM; +using KristofferStrube.Blazor.Window; +using System.Collections.Concurrent; namespace KristofferStrube.Blazor.WebWorkers; @@ -8,7 +10,14 @@ namespace KristofferStrube.Blazor.WebWorkers; public interface IJob { /// - /// How the job will send execute the job on the worker. + /// Initializes the job so that it is ready to be executed. + /// + /// The worker that the job should be runned on. + /// The dictionary that manages which executions finishes. + public abstract static Task> InitializeAsync(Worker worker, ConcurrentDictionary> pendingTasks); + + /// + /// Sends the to the . /// /// The type of the job. /// The input that the job should be executed with. diff --git a/src/KristofferStrube.Blazor.WebWorkers/JobWorker.cs b/src/KristofferStrube.Blazor.WebWorkers/JobWorker.cs index 11f75cd..2ea698b 100644 --- a/src/KristofferStrube.Blazor.WebWorkers/JobWorker.cs +++ b/src/KristofferStrube.Blazor.WebWorkers/JobWorker.cs @@ -13,9 +13,10 @@ namespace KristofferStrube.Blazor.WebWorkers; /// /// /// -public class JobWorker : Worker where TJob : IJob +public class JobWorker : Worker, IAsyncDisposable where TJob : IJob { private readonly ConcurrentDictionary> pendingTasks = new(); + private EventListener? messageListener; /// /// Creates a that can execute some specific on a worker thread. @@ -39,6 +40,8 @@ public class JobWorker : Worker where TJob : IJob ExecuteAsync(TInput input) { return await TJob.ExecuteAsync(input, this, pendingTasks); } + + /// + /// Diposes listener for events and the worker itself. + /// + public new async ValueTask DisposeAsync() + { + if (messageListener is not null) + { + await RemoveOnMessageEventListenerAsync(messageListener); + await messageListener.DisposeAsync(); + } + await base.DisposeAsync(); + } } diff --git a/src/KristofferStrube.Blazor.WebWorkers/JsonJob.cs b/src/KristofferStrube.Blazor.WebWorkers/JsonJob.cs index 5aa818c..ce80e0e 100644 --- a/src/KristofferStrube.Blazor.WebWorkers/JsonJob.cs +++ b/src/KristofferStrube.Blazor.WebWorkers/JsonJob.cs @@ -37,21 +37,12 @@ public TOutput ExecuteWithoutUsingWorker(TInput input) return outputSerializedAndDeserialized; } - /// - /// How an input is transfered to the for the . - /// - public static async Task ExecuteAsync(TInput input, Worker worker, ConcurrentDictionary> pendingTasks) where TJob : IJob + /// + public static async Task> InitializeAsync(Worker worker, ConcurrentDictionary> pendingTasks) { - string requestIdentifier = Guid.NewGuid().ToString(); - var tcs = new TaskCompletionSource(); - pendingTasks[requestIdentifier] = tcs; - EventListener eventListener = default!; eventListener = await EventListener.CreateAsync(worker.JSRuntime, async e => { - await worker.RemoveOnMessageEventListenerAsync(eventListener); - await eventListener.DisposeAsync(); - JobResponse response = await e.GetDataAsync(); if (pendingTasks.Remove(response.RequestIdentifier, out TaskCompletionSource? successTaskCompletionSource)) { @@ -68,6 +59,16 @@ public static async Task ExecuteAsync(TInput input, Worker worker await worker.AddOnMessageEventListenerAsync(eventListener); + return eventListener; + } + + /// + public static async Task ExecuteAsync(TInput input, Worker worker, ConcurrentDictionary> pendingTasks) where TJob : IJob + { + string requestIdentifier = Guid.NewGuid().ToString(); + var tcs = new TaskCompletionSource(); + pendingTasks[requestIdentifier] = tcs; + string inputSerialized = input is string stringInput ? stringInput : JsonSerializer.Serialize(input); @@ -95,7 +96,7 @@ public async Task StartAsync() if (inputSerialized is null) return; - TInput input = typeof(TInput) == typeof(string) && requestIdentifier is TInput stringInput + TInput input = typeof(TInput) == typeof(string) && inputSerialized is TInput stringInput ? stringInput : JsonSerializer.Deserialize(inputSerialized)!; diff --git a/src/KristofferStrube.Blazor.WebWorkers/TaskJsonJob.cs b/src/KristofferStrube.Blazor.WebWorkers/TaskJsonJob.cs index a3f0c08..82b3492 100644 --- a/src/KristofferStrube.Blazor.WebWorkers/TaskJsonJob.cs +++ b/src/KristofferStrube.Blazor.WebWorkers/TaskJsonJob.cs @@ -37,21 +37,13 @@ public async Task ExecuteWithoutUsingWorker(TInput input) return outputSerializedAndDeserialized; } - /// - /// How an input is transfered to the for the . - /// - public static async Task ExecuteAsync(TInput input, Worker worker, ConcurrentDictionary> pendingTasks) where TJob : IJob - { - string requestIdentifier = Guid.NewGuid().ToString(); - var tcs = new TaskCompletionSource(); - pendingTasks[requestIdentifier] = tcs; + /// + public static async Task> InitializeAsync(Worker worker, ConcurrentDictionary> pendingTasks) + { EventListener eventListener = default!; eventListener = await EventListener.CreateAsync(worker.JSRuntime, async e => { - await worker.RemoveOnMessageEventListenerAsync(eventListener); - await eventListener.DisposeAsync(); - JobResponse response = await e.GetDataAsync(); if (pendingTasks.Remove(response.RequestIdentifier, out TaskCompletionSource? successTaskCompletionSource)) { @@ -68,6 +60,18 @@ public static async Task ExecuteAsync(TInput input, Worker worker await worker.AddOnMessageEventListenerAsync(eventListener); + return eventListener; + } + + /// + /// How an input is transfered to the for the . + /// + public static async Task ExecuteAsync(TInput input, Worker worker, ConcurrentDictionary> pendingTasks) where TJob : IJob + { + string requestIdentifier = Guid.NewGuid().ToString(); + var tcs = new TaskCompletionSource(); + pendingTasks[requestIdentifier] = tcs; + string inputSerialized = input is string stringInput ? stringInput : JsonSerializer.Serialize(input); @@ -95,7 +99,7 @@ public async Task StartAsync() if (inputSerialized is null) return; - TInput input = typeof(TInput) == typeof(string) && requestIdentifier is TInput stringInput + TInput input = typeof(TInput) == typeof(string) && inputSerialized is TInput stringInput ? stringInput : JsonSerializer.Deserialize(inputSerialized)!;