Проблема потребления памяти в ядре Quartz.net - PullRequest
0 голосов
/ 28 мая 2019

Я использую Quartz.NET 3.0.7 в своем приложении для некоторых запланированных задач, но когда я запускаю планировщик, он увеличивает объем памяти, когда запускается планировщик. Я также проверял простую задачу расписания, которая выводит некоторый списокСтрока на консоли, та же проблема происходит в этом также. Я не могу понять, что является реальной проблемой. Мое наблюдение - IJob объект выпущен после того, как работа сделана. Я понятия не имею, кроме этого.

Я создаю задания динамически, передавая JobType

 private IJobDetail GetJobDetailForType<TInput>(string jobKey, string jobGroup) where TInput : IJob
    {
      IJobDetail jobDetail = JobBuilder.Create<TInput>()
                                       .WithIdentity(jobKey, jobGroup)
                                       .Build();
      return jobDetail;
    }

И инициализирую расписание заданий в этой функции

  private void InitializeSchedulerJob(ScheduleJob scheduleJob)
    {

        IJobDetail jobDetail;
        ITrigger trigger = this.GetTrigger(scheduleJob.Code.ToString(), tenantCode, scheduleJob.CornSchedule);

        if (scheduleJob.Code == (int)EnumHelper.Scheduler.Job.EmailJob)
        {
          this.logger.LogDebug($"EmailJob");
          jobDetail = this.GetJobDetailForType<EmailJob>(scheduleJob.Code.ToString(), tenantCode);
        }

        this.scheduler.ScheduleJob(jobDetail, trigger);
    }

Код задания электронной почты

 public class EmailJob : IJob 
  {
    private IServiceProvider serviceProvider;

    public EmailJob(IServiceProvider serviceProvider)
    {
      this.serviceProvider = serviceProvider;
    }

    public async Task Execute(IJobExecutionContext context)
    {
      if (this.serviceProvider != null)
      {
          JobKey jobKey = context.JobDetail.Key;
          IEmailScheduleSendService emailScheduleSendServiceNew = this.serviceProvider.GetRequiredService<IEmailScheduleSendService>();
          ILogger<EmailJob> logger = this.serviceProvider.GetRequiredService<ILogger<EmailJob>>();
          logger.LogDebug($"FROM EXECUTE METHOD | {jobKey.Name} | {jobKey.Group} | START");
          await emailScheduleSendServiceNew.EmailScheduleSendAsync(context);
          logger.LogDebug($"FROM EXECUTE METHOD | {jobKey.Name} | {jobKey.Group} | END");
        }
      }
    }

Ответы [ 2 ]

0 голосов
/ 05 июня 2019

Я предполагаю, что услуги, запрошенные вашим локатором услуг, не освобождаются после использования.Вы можете проверить это, внедрив интерфейс IDisposable в одну из запрошенных вами служб и убедившись, что вызывается Dispose().Я думаю, что нет.

Чтобы это исправить, вы можете зарегистрировать свои услуги как области и открыть область вручную.Это обеспечит утилизацию всех услуг после использования.

public async Task Execute(IJobExecutionContext context)
{
    // this check is superfluous and can be omitted. 
    // if you want to ensure that the service locator is there, check this in the constructor.
    // with a good DI framework, it can't be null.
    if (this.serviceProvider != null)
    {
        // open the scope and dispose it after use.
        using (var serviceScope = host.Services.CreateScope())
        {
            // get the service locator from the scope.
            var services = serviceScope.ServiceProvider;

            try
            {                   
                JobKey jobKey = context.JobDetail.Key;
                IEmailScheduleSendService emailScheduleSendServiceNew = services.GetRequiredService<IEmailScheduleSendService>();
                ILogger<EmailJob> logger = services.GetRequiredService<ILogger<EmailJob>>();
                logger.LogDebug($"FROM EXECUTE METHOD | {jobKey.Name} | {jobKey.Group} | START");
                await emailScheduleSendServiceNew.EmailScheduleSendAsync(context);
                logger.LogDebug($"FROM EXECUTE METHOD | {jobKey.Name} | {jobKey.Group} | END");
            }
            catch (Exception ex)
            {
                logger.LogDebug($"SOMETHING WENT WRONG!");
            }
        }
    }        
}
0 голосов
/ 28 мая 2019

Возможно, вы захотите запустить некоторые счетчики производительности, чтобы отслеживать использование ЦП и статистику памяти и выяснить, что происходит.

Если это не приводит к каким-либо очевидным ответам, пришло время приступить к профилированию.

...