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.
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);
}
}