I am trying to do polling from Angular to .NET Core API through BackgroundService.
I'll be passing inputs from the Angular component which calls the ApiController and that will trigger the BackgroundService and the outputs are updated back to the Angular Component in frequent intervals.
I've few queries.
ExecuteAsync
?ApiController
[ApiController]
[Route("[controller]")]
public class TestController : ControllerBase
{
private readonly ILogger<TestController> _logger;
public TestController(ILogger<TestController> logger)
{
_logger = logger;
}
[HttpGet]
public async Task<JsonResult> Get(CancellationToken cancellationToken)
{
var output = await Worker //How to call the worker here and then return the output?
return new JsonResult(output);
}
}
Worker
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
public Worker(ILogger<Worker> logger)
{
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
await Task.Delay(1000, stoppingToken);
// Process inputs and return outputs in frequent intervals
}
}
}
Angular Component
import { Component, Inject } from '@angular/core';
import { FormBuilder, FormGroup, FormControl, Validators } from '@angular/forms';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
})
export class HomeComponent {
public testForm: FormGroup;
public test = new FormControl('1');
constructor(private fb: FormBuilder,
http: HttpClient, @Inject('BASE_URL') baseUrl: string) {
const result = interval(2000)
.pipe(
switchMap(() => http.get(baseUrl + 'test')),
map(res => res))
result.subscribe(res => {
this.x.setValue(res);
})
}
}
There are many things here but I think You only interested in Calling worker.
So first step.
In ConfigureService services.AddScoped();
In Controller constructor.
private readonly ILogger _logger; private readonly Worker _worker; public TestController(ILogger logger,Worker worker) { _logger = logger; _worker = worker; }
[HttpGet]
public async Task<JsonResult> Get(CancellationToken cancellationToken)
{
var output = await ; //start worker
return new JsonResult(output);
}
There are two approach to start worker. If you have inherited from Background service then call StartAsync. If you have implemented IHostedService then you have to do it your own. https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-3.1&tabs=visual-studio
Note: I suspect that this approach will not give you update as you are awaiting for request to complete and before that result will not return.
Update
For Longer running background operation above approach will not work. For that you have to do some more work.
Note: If you want to avoid polling then based on use case you can use SignalR or websocket.