后台服务破坏了Web API性能

时间:2018-11-27 15:03:18

标签: c# asp.net-core .net-core asp.net-core-mvc asp.net-core-2.1

我目前正在开发移动应用程序使用的Web API。如果进行了需要发送电子邮件的API调用,则会将该电子邮件添加到Azure存储中的队列中。为了处理队列(阅读队列中的邮件并实际发送),我认为最好的解决方案是创建一个托管服务,该服务将在后台执行。

要实现此目的,我遵循了以下文档中的说明:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-2.1

我为此创建了一个类,该类实现了.NET Core 2.1中的抽象BackgroundService-class。看起来像这样:

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的所有其他调用几乎要花费十倍的时间。只有在我对BackgroundService的实现中注释掉Task.Delay()部分后,性能才能恢复到可接受的水平。

但是,这似乎比我的问题的实际解决方案更像是一种解决方法。我是否在做其他错误而使性能这样的坦克?

0 个答案:

没有答案