Fabloan
Fabloan

Reputation: 3

Is it possible to start multiple instances of a Thread or BackgroundWorker from a Blazor program, and start them inside .NET Aspire?

I want to run a worker (as Thread or BackgroundWorker) multiple times inside a .NET Aspire AppHost project, which is started from a Blazor Website.

I have the Projects (AppHost [Aspire], Web [Blazor], Worker [dll]).

Since I'm new to Aspire I don't know if this is even possible or how to do it.

I tried using the aspire builder.Services.AddHostedServices(); which did not work due to the namespace not being found because of the using Projects; which is needed for the blazor project as far as I understand.

I also tried registering it as a project which kinda worked.. well at least it started event if only once and only at the boot without any control over it via the web project.

Upvotes: 0

Views: 76

Answers (1)

Qiang Fu
Qiang Fu

Reputation: 8861

I don't think it is possible to run dynamically times instances in aspire. For one instance, you could expose endpoint to start/stop the worker which can be access using blazor httpclient. Such as following:
Aspire

builder.AddProject<Projects.WorkerService1>("workerservice1");

Worker project

var builder = WebApplication.CreateBuilder(args);
builder.AddServiceDefaults();
builder.Services.AddHostedService<Worker>();
var app = builder.Build();

app.MapGet("/", () => "Worker API is running...");
app.MapGet("/api/worker/start", async(ILogger<Worker> logger,HttpContext context) =>
{
    var worker = context.RequestServices.GetHostedService<Worker>();
    worker.StartService(); 
    logger.LogInformation("Start command received.");
    return   ("Worker started");
});

app.MapGet("/api/worker/stop", (ILogger<Worker> logger, HttpContext context) =>
{
    var worker = context.RequestServices.GetHostedService<Worker>();
    worker.StopService();
    logger.LogInformation("Stop command received.");
    return ("Worker stopped");
});
app.Run();

Worker.cs

public class Worker : BackgroundService
{
    private CancellationTokenSource _cts;

    public Worker()
    {
        _cts = new CancellationTokenSource();
    }
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!_cts.Token.IsCancellationRequested && !stoppingToken.IsCancellationRequested)
        {
            Console.WriteLine("myservice running");
            await Task.Delay(1000, stoppingToken);
        }
    }
    public void StopService()
    {
        _cts.Cancel();
    }
    public void StartService()
    {
        _cts = new CancellationTokenSource(); 
        ExecuteAsync(_cts.Token); 
    }
}

Blazor

@inject HttpClient Http
<h3>Worker Control</h3>
<button @onclick="StartWorker">Start Worker</button>
<button @onclick="StopWorker">Stop Worker</button>
@code {
    private async Task StartWorker()
    {
        await Http.PostAsync("http://worker-1/api/worker/start", null);
    }
    private async Task StopWorker()
    {
        await Http.PostAsync("http://worker-1/api/worker/stop", null);
    }
}

Upvotes: 0

Related Questions