Background Service ruining Web API performance
I'm currently developing a Web API used by our mobile application. If an API-call is made that needs to send an email, the email is added to a queue in Azure Storage. For handling the queue (reading the queue mails and actually sending them) I thought the best solution would be creating a Hosted Service that will do this in the background.
For implementing this I followed the instructions from the following documentation: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-2.1
I created a class that implements the abstract BackgroundService-class from .NET Core 2.1 for this. It looks like this:
namespace Api.BackgroundServices { /// <summary> /// Mail queue service. /// This handles the queued mails one by one. /// </summary> /// <seealso cref="Microsoft.Extensions.Hosting.BackgroundService" /> public class MailQueueService : BackgroundService { private readonly IServiceScopeFactory serviceScopeFactory; /// <summary> /// Initializes a new instance of the <see cref="MailQueueService"/> class. /// </summary> /// <param name="serviceScopeFactory">The service scope factory.</param> public MailQueueService(IServiceScopeFactory serviceScopeFactory) { this.serviceScopeFactory = serviceScopeFactory; } /// <summary> /// This method is called when the <see cref="T:Microsoft.Extensions.Hosting.IHostedService" /> starts. The implementation should return a task that represents /// the lifetime of the long running operation(s) being performed. /// </summary> /// <param name="stoppingToken">Triggered when <see cref="M:Microsoft.Extensions.Hosting.IHostedService.StopAsync(System.Threading.CancellationToken)" /> is called.</param> /// <returns>A <see cref="T:System.Threading.Tasks.Task" /> that represents the long running operations.</returns> protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { await HandleMailQueueAsync(); //await Task.Delay(3000, stoppingToken); } } private async Task HandleMailQueueAsync() { using (IServiceScope serviceScope = serviceScopeFactory.CreateScope()) { TelemetryClient telemetryClient = serviceScope.ServiceProvider.GetService<TelemetryClient>(); try { IMailHandler mailHandler = serviceScope.ServiceProvider.GetService<IMailHandler>(); await mailHandler.HandleMailQueueAsync(); } catch (Exception exception) { telemetryClient.TrackException(exception); } } } } }
After registering it by calling
services.AddHostedService<MailQueueService>();
in the Startup.cs, it will successfully handle the mail queue, but all other calls to the WebAPI take almost ten times as long. Only if I comment out the Task.Delay() part in my implementation of the BackgroundService, the performance goes back to an acceptable level.
However this seems more like a workaround than a real solution for my problem. Am I doing something else wrong that makes the performance tank like this?
0 comments:
Post a Comment