Фоновая служба снижает производительность веб-API - PullRequest
0 голосов
/ 27 ноября 2018

В настоящее время я разрабатываю веб-API, используемый нашим мобильным приложением.Если выполняется вызов API, который должен отправить электронное письмо, оно добавляется в очередь в хранилище Azure.Для обработки очереди (чтения почты очереди и ее фактической отправки) я подумал, что лучшим решением будет создание размещенной службы, которая будет делать это в фоновом режиме.

Для реализации этого я следовал инструкциям из следующей документации: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-2.1

Я создал класс, который реализует абстрактный BackgroundService-класс из .NET Core 2.1 для этого.Это выглядит так:

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

После регистрации, вызвав

services.AddHostedService<MailQueueService>();

в Startup.cs, он успешно обработает почтовую очередь, но все другие вызовы WebAPI принимаютпочти в десять раз длиннееТолько если я закомментирую часть Task.Delay () в моей реализации BackgroundService, производительность вернется к приемлемому уровню.

Однако это больше похоже на обходной путь, чем на реальное решение моей проблемы.Я что-то не так делаю, что делает танк производительности вот таким?

...