In Blazor wasm, I would like to periodically execute a job (code), even if the user is navigating through the pages (every x min for example).
Is that possible? What would be a practical way?
Create a Service to manage the timer
public class JobExecutedEventArgs : EventArgs {}
public class PeriodicExecutor : IDisposable
{
public event EventHandler<JobExecutedEventArgs> JobExecuted;
void OnJobExecuted()
{
JobExecuted?.Invoke(this, new JobExecutedEventArgs());
}
Timer _Timer;
bool _Running;
public void StartExecuting()
{
if (!_Running)
{
// Initiate a Timer
_Timer= new Timer();
_Timer.Interval = 300_000; // every 5 mins
_Timer.Elapsed += HandleTimer;
_Timer.AutoReset = true;
_Timer.Enabled = true;
_Running = true;
}
}
void HandleTimer(object source, ElapsedEventArgs e)
{
// Execute required job
// Notify any subscribers to the event
OnJobExecuted();
}
public void Dispose()
{
if (_Running)
{
// Clear up the timer
}
}
}
Register it in Program.cs
builder.Services.AddSingleton<PeriodicExecutor>();
Request it and start it in home page initialization
@page "/home"
@inject PeriodicExecutor PeriodicExecutor
@code {
protected override void OnInitialized()
{
PeriodicExecutor.StartExecuting();
}
}
In any component if you want to do something when job executes
@inject PeriodicExecutor PeriodicExecutor
@implements IDisposable
<label>@JobNotification</label>
@code {
protected override void OnIntiialized()
{
PeriodicExecutor.JobExecuted += HandleJobExecuted;
}
public void Dispose()
{
PeriodicExecutor.JobExecuted -= HandleJobExecuted;
}
string JobNotification;
void HandleJobExecuted(object sender, JobExecutedEventArgs e)
{
JobNotification = $"Job Executed: {DateTime.Now}";
StateHasChanged();
}
}
If you are using an ASP.NET Core Hosted flavor of Blazor WebAssembly, you can use a BackgroundService. For example:
MyBackgroundService.cs
public class MyBackgroundService : BackgroundService
{
private readonly ILogger<CollectionService> _logger;
private readonly IServiceScopeFactory _serviceScopeFactory;
public MyBackgroundService(ILogger<CollectionService> logger, IServiceScopeFactory serviceScopeFactory)
{
_logger = logger;
_serviceScopeFactory = serviceScopeFactory;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("My Background Service is starting.");
//Do your work here...
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<MyBackgroundService>();
services.AddHostedService(provider => provider.GetService<MyBackgroundService>());
One benefit of this solution is the service will start running regardless of whether a user navigates to any particular page on the site. Or even if no user access the site.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With