Asked by:
Add more than one task to my worker class (BackgroundService ASP.Net Core 3.1)

Question
-
User-158191824 posted
Using ASP.Net Core 3.1, I have a simple background task which is working successfully :
public class UserActivitiesCleaner : BackgroundService { private readonly IWorker worker; public UserActivitiesCleaner(IWorker worker) { this.worker = worker; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { await worker.DoWork(stoppingToken); } }
Here is my current worker:
public class Worker : IWorker { private readonly IServiceScopeFactory serviceProvider; public Worker(IServiceScopeFactory serviceProvider) { this.serviceProvider = serviceProvider; } public async Task DoWork(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { using (var scope = serviceProvider.CreateScope()) { var _unitOfWork = scope.ServiceProvider.GetRequiredService<IUnitOfWork>(); while (!stoppingToken.IsCancellationRequested) { await _unitOfWork.userActivityRepository.DeleteByDapper(); await Task.Delay(1000 * 3600); } } } } }
The problem is : I need to know if I can have another task with different delay time in the same worker without creating a new worker : ( looking for simplicity) So I tried this :
public async Task DoWork(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { using (var scope = serviceProvider.CreateScope()) { var _unitOfWork = scope.ServiceProvider.GetRequiredService<IUnitOfWork>(); while (!stoppingToken.IsCancellationRequested) { await _unitOfWork.userActivityRepository.DeleteByDapper(); await Task.Delay(1000 * 3600); } while (!stoppingToken.IsCancellationRequested) { await _unitOfWork.userActivityRepository.DoSomethingElse(); await Task.Delay(TimeSpan.FromDays(1)); } } } }
but the code never enters the second while-loop, in the time that the program is running . Any idea of having more than one task in a worker is appreciated..
Tuesday, November 17, 2020 5:13 AM
All replies
-
User475983607 posted
Use a timer not a delay.
https://docs.microsoft.com/en-us/dotnet/api/system.timers.timer?view=net-5.0
Wednesday, November 18, 2020 8:07 PM -
User-158191824 posted
So after saying thanks, the code will be something like this, I couldn't manage `BackgroundService` so changed to `IHostedService` . It is working but I need to know if it is true or not ? And I do not know if the code is async or not, cause I can't use await while I want to query on my database
I want to use await in the following code without getting errors..
public class UserActivitiesManager : IHostedService, IDisposable { private readonly ILogger<UserActivitiesManager> _logger; private readonly IServiceScopeFactory serviceProvider; public UserActivitiesManager(ILogger<UserActivitiesManager> logger, IServiceScopeFactory serviceProvider) { _logger = logger; this.serviceProvider = serviceProvider; } private Timer _timer; public Task StartAsync(CancellationToken cancellationToken) { _timer = new Timer(DoWork1Async, null, TimeSpan.Zero, TimeSpan.FromSeconds(5)); _timer = new Timer(DoWork2, null, TimeSpan.Zero, TimeSpan.FromSeconds(10)); return Task.CompletedTask; } private void DoWork1Async(object state) { using (var scope = serviceProvider.CreateScope()) { var _unitOfWork = scope.ServiceProvider.GetRequiredService<IUnitOfWork>(); _unitOfWork.userActivityRepository.ChangeByDapper(); _logger.LogError($"{DateTime.Now.TimeOfDay} ---- I am task of DoWork1"); }; } private void DoWork2(object state) { using (var scope = serviceProvider.CreateScope()) { var _unitOfWork = scope.ServiceProvider.GetRequiredService<IUnitOfWork>(); _unitOfWork.userActivityRepository.DeleteByDapper(); _logger.LogError($"{DateTime.Now.TimeOfDay} ---- I am task of DoWork2"); }; } public Task StopAsync(CancellationToken cancellationToken) { return Task.CompletedTask; } public void Dispose() { _timer?.Dispose(); } }
Thursday, November 19, 2020 9:39 AM -
User1312693872 posted
Hi,ehsan_kabiri_33
The BackgroundService class is new in ASP.NET Core 3.0 and is basically an abstract class that already implements the IHostedService Interface.
I want to use await in the following code without getting errors..await can't be used in void, you should change your void to async:
public virtual async Task StopAsync(CancellationToken cancellationToken) { await Task.CompletedTask; }
You can also check the following links:
https://medium.com/@daniel.sagita/backgroundservice-for-a-long-running-work-3debe8f8d25b
https://girishgodage.in/blog/customize-hostedservices
Best Regards,
Jerry Cai.
Wednesday, November 25, 2020 8:09 AM