我有一个托管服务,每分钟检查一次电子邮件帐户。我还将MVC与Web API 2.1一起使用。为了启动我的托管服务,我必须通过调用API方法来“唤醒”它。 Web API闲置一段时间后,托管服务进入睡眠状态并停止检查电子邮件。就像它正在收集垃圾一样。如何使它连续运行?
我们将不胜感激。
Startup.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();
}
}
答案 0 :(得分:3)
如您所想,根本原因是由于在IIS中进行托管时,由于应用程序池回收,您的主机可能被关闭。这已在下面指出:
请务必注意,部署ASP.NET Core WebHost或.NET Core Host的方式可能会影响最终解决方案。例如,如果您将WebHost部署在IIS或常规的Azure App Service上,则由于应用程序池回收,主机可能会被关闭。
Deployment considerations and takeaways
对于一个可能的解决方法,您可以尝试将空闲超时设置为零以禁用默认回收。
由于IIS的默认回收,您可以考虑使用不同的托管方法:
使用Windows服务
使用Docker容器(Windows容器),但为此,您需要Windows Server 2016或更高版本。
使用Azure功能
对于您的情况,您可以尝试Host ASP.NET Core in a Windows Service
答案 1 :(得分:0)
我在Windows Event Scheduler上创建任务以访问URL来唤醒服务。
powershell.exe-命令{Invoke-WebRequest http://localhost:8080}