我有以下界面
internal interface IScopedProcessingService
{
Task DoWork(CancellationToken stoppingToken);
}
Run Code Online (Sandbox Code Playgroud)
和实施
public class ConsumeScopedServiceHostedService : BackgroundService
{
private readonly ILogger<ConsumeScopedServiceHostedService> _logger;
public ConsumeScopedServiceHostedService(IServiceProvider services,
ILogger<ConsumeScopedServiceHostedService> logger)
{
Services = services;
_logger = logger;
}
public IServiceProvider Services { get; }
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation(
"Consume Scoped Service Hosted Service running.");
await DoWork(stoppingToken);
}
private async Task DoWork(CancellationToken stoppingToken)
{
_logger.LogInformation(
"Consume Scoped Service Hosted Service is working.");
using (var scope = Services.CreateScope())
{
var scopedProcessingService =
scope.ServiceProvider …Run Code Online (Sandbox Code Playgroud) c# entity-framework-core .net-core asp.net-core-hosted-services
我有以下包含托管服务的简单控制台应用程序:
public static async Task Main(string[] args)
{
using (var host = Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
// db context
services.AddEntityFrameworkNpgsql()
.AddDbContext<ApplicationDbContext>();
// hosted services
services.AddHostedService<ConsumeScopedServiceHostedService>();
services.AddScoped<ProcessManuallySendings>();
// services
services.AddHttpClient<ISendPushService, SendPushService>(x
=>
{
x.Timeout = TimeSpan.FromSeconds(65);
});
})
.Build())
{
// Start the host
await host.StartAsync();
// Wait for the host to shutdown
await host.WaitForShutdownAsync();
}
}
}
Run Code Online (Sandbox Code Playgroud)
它适用于我的数据库,这意味着它需要连接字符串。我有三个appsettings.json文件:
在开发服务器上,我将使用Development环境,在生产服务器上 - Production. 在我的本地机器上,我将使用Local. 这很简单。我将在ASPNETCORE_ENVIRONMENT(操作系统环境变量)的帮助下获得它。
我使用 Linux,在我的 shell (zsh) 配置文件中,我有:
当我输入终端时,$ …
c# .net-core asp.net-core-hosted-services aspnetcore-environment
我有一个带有简单消费后台服务的控制台程序,它需要从使用 HttpClientFactory 的作用域服务调用函数来调用外部 API 并将结果返回给消费后台服务。
在网上查看了几个示例后,我想要非常简单,以消除代码中所有可能的复杂性。
public class Program
{
public static async Task Main(string[] args)
{
var host = new HostBuilder()
.ConfigureLogging((hostContext, config) =>
{
config.AddConsole();
})
.ConfigureAppConfiguration((hostContext, config) =>
{
config.AddJsonFile("appsettings.json", optional: true);
config.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true);
config.AddCommandLine(args);
})
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<ConsumeMessageService>();
services.AddScoped<IScopedArcGisServices, ScopedArcGisServices>();
})
.UseConsoleLifetime()
.Build();
using (host)
{
// Start the host
await host.StartAsync();
// Wait for the host to shutdown
await host.WaitForShutdownAsync();
}
}
}
Run Code Online (Sandbox Code Playgroud)
public class ConsumeMessageService : IHostedService
{
private …Run Code Online (Sandbox Code Playgroud) c# dependency-injection httpclientfactory asp.net-core-hosted-services
我有以下计时器在 .Net 核心 Ihosted 服务中运行,
TimeSpan ScheduledTimespan;
string[] formats = { @"hh\:mm\:ss", "hh\\:mm" };
string strTime = Startup.Configuration["AppSettings:JobStartTime"].ToString();
var success = TimeSpan.TryParseExact(strTime, formats, CultureInfo.InvariantCulture, out ScheduledTimespan);
Timer _timer = new Timer(JobToRun, null, TimeSpan.Zero, ScheduledTimespan);
Run Code Online (Sandbox Code Playgroud)
我正在使用这个特定的重载,
public Timer(TimerCallback callback, object state, TimeSpan dueTime, TimeSpan period);
Run Code Online (Sandbox Code Playgroud)
但是JobToRun一旦控制到达它就会执行。如何让它在每天的特定时间运行?提前致谢。
在我们的 ASP.Net Core Web API 中,我们曾经Hosted Services执行过一些后台任务。有时这些后台任务可能需要很长时间才能完成(大约一个小时)。除非有长时间运行的任务,否则一切都可以无缝运行。
IIS 应用程序池的空闲超时默认值为 20 分钟。因此,当 20 分钟内没有请求时,IIS 会重新启动应用程序池。但有时后台任务可能会运行并且 IIS 重新启动,而不管它是否会导致任务突然终止而没有将其标记为完成。一旦 IIS 启动,托管服务启动处理就会再次选取任务。但在完成之前,IIS 会重新启动,并且这种情况可能会一直持续下去。当存在可能多次发送相同电子邮件的电子邮件发送任务时,这可能会导致许多问题。
由于托管服务是 ASP.NET Core 的一等公民,如果 IIS 在执行空闲超时时也考虑后台执行,那将是理想的。
现在我们通过将空闲超时设置为 0 来解决这个问题,这样它就永远不会超时。这是一种hacky解决方案。此外,在节点动态添加和删除的负载平衡环境中,这不是一个可行的选择。
有没有更好的方法来“防止 IIS 在后台执行过程中重新启动”?
谢谢
asp.net iis .net-core asp.net-core asp.net-core-hosted-services
我正在创建一个工作服务,它将作为 Windows 服务运行。我有一个要求,我想调用两个可能有不同计时器的任务。
SayDoWork应该每 5 分钟调用一次,并且DoAnotherWork应该每 10 分钟左右调用一次。这两个任务可以并行运行,互不依赖。
我能够创建DoWork可以每 5 分钟运行一次的任务。我对如何实现另一个具有不同计时器持续时间的任务感到有些困惑?
public class Worker : BackgroundService
{
private readonly IServiceScopeFactory _scopeFactory;
private IDataLoaderService _dataLoaderService;
public override Task StartAsync(CancellationToken cancellationToken)
{
using var scope = _scopeFactory.CreateScope();
_dataLoaderService = scope.ServiceProvider.GetRequiredService<IDataLoaderService>();
return base.StartAsync(cancellationToken);
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
await DoWork(stoppingToken, _dataLoaderService);
await Task.Delay(300000, stoppingToken); //Run every 5 minutes
await DoAnotherWork(stoppingToken, _dataLoaderService);
await Task.Delay(600000, stoppingToken); //Run every 10 minutes
}
}
private …Run Code Online (Sandbox Code Playgroud) 我正在开发一个 ASP.NET Core MVC Web 应用程序,其中有两个任务应该作为后台服务运行:
经过搜索,我发现可以使用 Service Worker 来实现这一点。但我完全困惑如何在现有的 ASP.NET Core MVC Web 应用程序中使用这个服务工作者,我需要访问我的模型和数据库。
我应该将这些任务隔离在单独的 Service Worker 项目中吗?但在这种情况下,我应该为两个项目共享相同的数据库吗?
有人可以指导我在这种情况下的主要步骤吗?
先感谢您。
我需要在特定时间触发托管服务,例如。每天13:00。我的典型 ExecuteAsync 方法似乎是这样的:
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
var interval = _configuration.IntervalInSeconds * 1000;
while (!stoppingToken.IsCancellationRequested)
{
// some job
await Task
.Delay(interval, stoppingToken);
}
}
Run Code Online (Sandbox Code Playgroud)
例如,当应用程序启动时,会调用 executeAsync 方法,然后每分钟都会发生一些操作。现在我必须只在特定时间执行这样的操作。有什么方法可以实现这种行为吗?除了粗略计算下一次触发时间之外,我的问题还有什么解决方案吗??谢谢你的帮助。
所以我有一个 dotnet 核心工作进程,我想在某些情况下关闭工作进程。
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("This is a worker process");
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
if (condition == true)
//do something to basically shutdown the worker process with failure code.
await Task.Delay(2000, stoppingToken);
}
}
Run Code Online (Sandbox Code Playgroud)
我怎样才能做到这一点?我试图跳出循环,但这并没有真正关闭工作进程。
//----this does not work-----
//even after doing this, Ctrl-C has to be done to shutdown the worker.
if (condition == true) break;
Run Code Online (Sandbox Code Playgroud) 在 .NET 6 中创建多个后台任务,这些任务在功能方面彼此独立,并根据计划的时间并行/同时运行。使用 Worker 类模板,我能够创建多个托管/后台服务,并且它们按预期运行。
但services.AddHostedService<Worker>();将被视为 Singleton 类,我们需要解决作用域依赖关系,以使服务具有作用域,遵循作用域服务文档中的相同内容。根据上面链接中的示例,示例代码如下所示,作用域服务的接口
namespace App.ScopedService;
public interface IScopedProcessingService
{
Task DoWorkAsync(CancellationToken stoppingToken);
}
Run Code Online (Sandbox Code Playgroud)
以及接口的默认实现
namespace App.ScopedService;
public class DefaultScopedProcessingService : IScopedProcessingService
{
private int _executionCount;
private readonly ILogger<DefaultScopedProcessingService> _logger;
public DefaultScopedProcessingService(
ILogger<DefaultScopedProcessingService> logger) =>
_logger = logger;
public async Task DoWorkAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
++ _executionCount;
_logger.LogInformation(
"{ServiceName} working, execution count: {Count}",
nameof(DefaultScopedProcessingService),
_executionCount);
await Task.Delay(10_000, stoppingToken);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是后台服务实现
namespace App.ScopedService;
public sealed class ScopedBackgroundService …Run Code Online (Sandbox Code Playgroud) c# background-service asp.net-core asp.net-core-hosted-services .net-6.0
asp.net-core-hosted-services ×10
c# ×8
.net-core ×7
asp.net-core ×4
.net-6.0 ×1
asp.net ×1
iis ×1
timer ×1