C# 同时运行长任务IHosted服务,可以手动打开和关闭
您好,我在使用IHostedService为我的后台服务运行一个长任务时遇到了问题。起初,它确实工作正常,但从长远来看,后台服务突然停止,出现以下线程退出代码:C# 同时运行长任务IHosted服务,可以手动打开和关闭,c#,asp.net-core,backgroundworker,asp.net-core-hosted-services,C#,Asp.net Core,Backgroundworker,Asp.net Core Hosted Services,您好,我在使用IHostedService为我的后台服务运行一个长任务时遇到了问题。起初,它确实工作正常,但从长远来看,后台服务突然停止,出现以下线程退出代码: The thread 10824 has exited with code 0 (0x0). The thread 12340 has exited with code 0 (0x0). The thread 9324 has exited with code 0 (0x0). The thread 11168 has exited w
The thread 10824 has exited with code 0 (0x0).
The thread 12340 has exited with code 0 (0x0).
The thread 9324 has exited with code 0 (0x0).
The thread 11168 has exited with code 0 (0x0).
The thread 11616 has exited with code 0 (0x0).
The thread 9792 has exited with code 0 (0x0).
我将我的后台服务注册为
//Register Background
serviceCollection.AddSingleton<CoinPairBackgroundService>
serviceCollection.AddSingleton<SaveFakePersonBackgroundService>();
serviceCollection.AddSingleton<LeaderboardMinutesBackgroundService>();
serviceCollection.AddSingleton<LeaderboardHoursBackgroundService>();
serviceCollection.AddSingleton<IHostedService, CoinPairBackgroundService>();
serviceCollection.AddSingleton<IHostedService, SaveFakePersonBackgroundService>();
serviceCollection.AddSingleton<IHostedService, LeaderboardMinutesBackgroundService>();
serviceCollection.AddSingleton<IHostedService, LeaderboardHoursBackgroundService>();
我对注册我的后台服务是否有问题感到困惑,因为我看到我的后台服务启动了,但从长远来看,它突然停止了。我已经摆脱了那些线程。我的后台服务中的Sleep()希望你能提前帮到我,谢谢。而不是以如此奇怪的方式管理托管服务的生命周期,您可以为
appsettings.json
内的服务设置配置,将其配置为reloadOnChange:true
,并使用IOptionsMonitor
从appsettings.json
访问当前值。并将该设置用作在托管服务的StartAsync
方法中取消已启动的任务。您需要收听IOptionsMonitor
的OnChange
事件以重新启动服务
appsettings.json
:
"HostedService": {
"RunService1": true
}
注册该选项,以便:
public class HostedServiceConfig
{
public bool RunService1 { get; set; }
}
services.Configure<HostedServiceConfig>(Configuration.GetSection("HostedService"));
下面是StartAsync
的示例:
public class HostedService1 : IHostedService
{
private readonly IOptionsMonitor<HostedServiceConfig> _options;
private CancellationToken _cancellationToken;
public HostedService1(IOptionsMonitor<HostedServiceConfig> options)
{
_options = options;
// Or listen to changes and re-run all services from one place inside `Configure` method of `Startup`
_options.OnChange(async o =>
{
if (o.RunService1)
{
await StartAsync(_cancellationToken);
}
});
}
public Task StartAsync(CancellationToken cancellationToken)
{
if(_cancellationToken == null)
{
_cancellationToken = cancellationToken;
}
Task.Run(async () =>
{
while (!_cancellationToken .IsCancellationRequested || !_options.CurrentValue.RunService1)
{
....
}
});
return Task.CompletedTask;
}
...
}
公共类HostedService 1:IHostedService
{
专用只读IOptionsMonitor选项;
私有取消令牌\u取消令牌;
公共托管服务1(IOptionsMonitor选项)
{
_选项=选项;
//或者在“启动”的“配置”方法中,侦听更改并从一个位置重新运行所有服务`
_options.OnChange(异步o=>
{
如果(o.RunService1)
{
等待StartSync(_cancellationToken);
}
});
}
公共任务StartSync(CancellationToken CancellationToken)
{
if(_cancellationToken==null)
{
_cancellationToken=cancellationToken;
}
Task.Run(异步()=>
{
while(!\u cancellationToken.IsCancellationRequested | |!\u options.CurrentValue.RunService1)
{
....
}
});
返回Task.CompletedTask;
}
...
}
如果
appSettings.json
中有任何更改,您的\u options.CurrentValue.RunService1
将自动重新加载。为什么要注册两次?为什么不使用AddHostedService
?@FarhadJabiyev,这是因为我无法在不首先注册实现IHostedService的具体类的情况下获得IHostedService,正如您所看到的,我使用的是StartAsync()和StopAsync()手动打开和关闭我的BackgroundService的iHosteService功能在配置服务时决定运行哪些服务是不好的。相反,只需在appsettings.json
中创建其他配置,并检查StartAsync
中的值即可。如果已关闭,则只返回已完成的结果。@FarhadJabiyev这意味着我的appsettings.json中将有一个变量更改了其用于打开和关闭后台服务的值?如果我有多个后台服务,这意味着我的appsettings.json中的变量太多了怎么办?这是appsettings存在的原因,但我的问题是,当后台服务在StartAsync()中中断循环时,如何重新启动后台服务?有没有办法让这个HostedService 1再次运行?@JamesTubiano哦,明白了,你需要自动重新启动它?或者从appsettings
手动启动是否正常?我想手动重新启动它是否有任何方法可以使用appsettings手动启动和停止HostedService 1?
public class HostedServiceConfig
{
public bool RunService1 { get; set; }
}
services.Configure<HostedServiceConfig>(Configuration.GetSection("HostedService"));
services.AddHostedService<HostedService1>();
public class HostedService1 : IHostedService
{
private readonly IOptionsMonitor<HostedServiceConfig> _options;
private CancellationToken _cancellationToken;
public HostedService1(IOptionsMonitor<HostedServiceConfig> options)
{
_options = options;
// Or listen to changes and re-run all services from one place inside `Configure` method of `Startup`
_options.OnChange(async o =>
{
if (o.RunService1)
{
await StartAsync(_cancellationToken);
}
});
}
public Task StartAsync(CancellationToken cancellationToken)
{
if(_cancellationToken == null)
{
_cancellationToken = cancellationToken;
}
Task.Run(async () =>
{
while (!_cancellationToken .IsCancellationRequested || !_options.CurrentValue.RunService1)
{
....
}
});
return Task.CompletedTask;
}
...
}