我有一个托管服务,每分钟检查一个电子邮件帐户。我还将 MVC 与 Web API 2.1 一起使用。为了让我的托管服务启动,我必须通过调用 API 方法来“唤醒它”。在 Web API 一段时间不活动后,托管服务进入睡眠状态并停止检查电子邮件。就像它正在收集垃圾一样。如何让它连续运行?
协助将不胜感激。
启动.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info {Title = "CAS API", Version = "v1"});
// Set the comments path for the Swagger JSON and UI.
var xmlFile = $"{Assembly.GetEntryAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);
})
.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.WithOrigins(Configuration["uiOrigin"])
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
})
.AddHostedService<EmailReceiverHostedService>()
.Configure<EmailSettings>(Configuration.GetSection("IncomingMailSettings"))
.AddSingleton<IEmailProcessor, MailKitProcessor>()
.AddSingleton<IEmailRepository, EmailRepository>()
...
EmailReceiverHostedService.cs:
using CasEmailProcessor.Options;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Threading;
using System.Threading.Tasks;
public class EmailReceiverHostedService : IHostedService, IDisposable
{
private readonly ILogger _logger;
private readonly Timer _timer;
private readonly IEmailProcessor _processor;
private readonly EmailSettings _emailConfig;
public EmailReceiverHostedService(ILoggerFactory loggerFactory,
IOptions<EmailSettings> settings,
IEmailProcessor emailProcessor)
{
_logger = loggerFactory.CreateLogger("EmailReceiverHostedService");
_processor = emailProcessor;
_emailConfig = settings.Value;
_timer = new Timer(DoWork, null, Timeout.Infinite, Timeout.Infinite);
}
public Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Timed Background Service is starting.");
StartTimer();
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Timed Background Service is stopping.");
StopTimer();
return Task.CompletedTask;
}
public void Dispose()
{
_timer?.Dispose();
}
private void StopTimer()
{
_timer?.Change(Timeout.Infinite, 0);
}
private void StartTimer() { _timer.Change(TimeSpan.FromSeconds(_emailConfig.TimerIntervalInSeconds), TimeSpan.FromSeconds(_emailConfig.TimerIntervalInSeconds)); }
private void DoWork(object state)
{
StopTimer();
_processor.Process();
StartTimer();
}
}