Tewr / BlazorWorker

Library for creating DotNet Web Worker threads/multithreading in Client side Blazor
MIT License
391 stars 36 forks source link

Net8 Support -- BlazorWorker: Unable to locate dotnetjs file in blazor boot #90

Closed dodyg closed 10 months ago

dodyg commented 1 year ago

I found this error BlazorWorker: Unable to locate dotnetjs file in blazor boot at the web browser log. I am using .NET WASM 8 RC1. Do I miss anything?

at Program.cs

services.AddWorkerFactory();

at Razor

public class NotificationService (IWorkerMessageService workerMessage)
{
    public async Task DoAsync()
    {
        await workerMessage.PostMessageAsync("Hello world");
    }
}

    protected override async Task OnInitializedAsync()
    {
        _worker = await workerFactory.CreateAsync();
        _worker.IncomingMessage += OnWorkerMessage;

        _backgroundService = await _worker.CreateBackgroundServiceAsync<NotificationService>();
        await _backgroundService.RunAsync(x => x.DoAsync());
    }

    void OnWorkerMessage(object? sender, string message)
    {
        Log($"Receive Message {message}", LogType.Error);
    }
dodyg commented 1 year ago

Most probably related to this https://github.com/Tewr/BlazorWorker/issues/85

Tewr commented 1 year ago

Yes most likely. The breaking changes of net7 are not likely to have been reverted in net 8

Tewr commented 1 year ago

This is a new breaking change in the bootstrapper. For net8 the blazorboot is reconstructed quite heavily with the runtime being split up in two files, dotnet.native.8.0.0.ot6jeefn53.js and dotnet.runtime.8.0.0.1khq4boqw1.js. I'm going to have to do some reading to solve this

Tewr commented 11 months ago

I've made some progress here tonight, but Crucial JsInterop fails without error https://github.com/Tewr/BlazorWorker/pull/91

Tewr commented 11 months ago

Some notes on progress.

Some further investigation show that while JsInterop seems to work OK, Tasks does not seem to work correctly. I can finalize the service Init message loop without errors, as the service init function is fully synchronous. That is, I send a message to initialize a service in the worker, and the service starts, and sends a "initialized" message back to the UI thread without problems.

So the dotnet environments starts, and functions can be executed as long as they are synchronous or does not provoke an actual Task switch. If a task is force started with Task.Run, it never executed. if I attempt to await Task.Delay, the calling function seems to freeze over. The details need to be investigated further, but at a first glance the first Task which is not the main Task and thus run on the Task scheduler is stuck in WaitingForActivation status.

It is possible that there are some new defaults for the Task scheduler when starting the runtime? That makes it default to a single task when running on a worker. Some kind of different behaviour when detecting that being run in a worker. Maybe some side effect from the work that has already started on multithreading in the runtime.

TrixxTraxx commented 11 months ago

I would really like this to be fixed. Would it be possible to push a build that only supports syncronous workloads?

Tewr commented 11 months ago

I haven't been able to reproduce a fully working runtime even while avoiding the triggering of a task switch. Something is missing.

The following linked issue plans to post/blog some kind of guide, might be useful but seems like they are planning for a demo using a separate template and a separate build, which is a bit sad, cause it's a lot more work

https://github.com/dotnet/runtime/issues/95452

Tewr commented 11 months ago

Some good news after climbing down the rabbit hole: need more investigation but await dotnet.run(); , which was introduced by me while testing .net7, seems to be the culprit.

Seems to work fine after removing this line. Something has changed in .net8 which make this line break the runtime. In any case this line is useless as all it does is call Program.Main() which is needed for nothing.

If this is really the case, I might be able to get out a beta version in a few days. I need to get some kind of basic multitargeting code in place first

pavelsavara commented 11 months ago

await dotnet.run() In any case this line is useless as all it does is call Program.Main() which is needed for nothing.

That is indeed just running main.

@maraf we should update our template to make it clear users don't have to call this.

Something has changed in .net8 which make this line break the runtime.

The change is that we will properly "exit" the "process" after main is finished.

Tewr commented 10 months ago

.net8 support works in https://github.com/Tewr/BlazorWorker/releases/tag/v4.0.0-preview2 , try it out.