在自托管ASP.NET Core微服务中启动多个后台线程 [英] Start multiple background threads inside Self Hosted ASP.NET Core Microservice
问题描述
我在哪里可以在Self Hosted Self Contained ASP.NET Core Microservice
中创建多个长期运行的后台线程,它们的生存期与微服务生存期相同?这样,从线程中检索到的信息就可以作为对请求的响应而发送.
Where can i create multiple long running background threads in Self Hosted Self Contained ASP.NET Core Microservice
whose lifetime is same as micro-service lifetime? So that information retrieved from threads can be sent as a response to the requests.
尝试使用给定的代码,但是当后台线程繁忙时,它会降低http请求的性能. Program.cs文件的主要方法是:
Tried given code but it reduces http request performance when background threads are busy. Main method of Program.cs file is:
static void Main(string[] args)
{
//Start background thread1
//Start background thread2
//Around 10 background threads
//Start host
var host = new WebHostBuilder()
.UseKestrel()
.UseUrls(ServerUrl)
.UseConfiguration(config)
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.ConfigureServices(s => s.AddRouting())
.Configure(app => app.UseRouter(r => { (new Router()).Route(r); }))
.Build();
host.Run();
}
线程以这种方式工作:
Thread t1 = new Thread(StartWork);
t1.IsBackground = true;
t1.Start();
public void StartWork()
{
while (ApplicationIsRunning)
{
//Get database info >> login into remote devices (SSH) >> get information >> process information >> update application variables and database
Thread.Sleep(10000);
}
}
当线程繁忙但http请求性能仍然很差时,CPU利用率仅为1-5%.进入睡眠状态后,性能再次提高.
CPU utilization is only 1-5% when threads are busy but still http request performance is very bad. After going to sleep state performance again improves.
问题出在SSH客户端连接的连接方法上.在某些时候,connect方法没有响应,并且还会影响所有其他线程.真奇怪!
The issue is at connect method of SSH client connection. At some point connect method is not responding and it affect all other threads also. That is strange!
Renci.SshNet.SshClient sshClient = New Renci.SshNet.SshClient(sshConnectionInfo);
sshClient.Connect();
如果一个线程由于任何原因忙于连接,则不应影响其他线程.
If one thread is busy in connection because of any reason it should not affect other threads.
推荐答案
代码可能来自史蒂夫·戈登(Steve Gordon)的帖子,网址为
code possibly from Steve Gordon's post at https://www.stevejgordon.co.uk/asp-net-core-2-ihostedservice ?
确保您可以:) 使用IHostedService(.net核心提供的即用型),您可以实现以下功能:
sure you can :) With IHostedService (out-of-the-box from .net core) you can implement the following:
public abstract class HostedService : IHostedService
{
private Task _executingTask;
private CancellationTokenSource _cts;
public Task StartAsync(CancellationToken cancellationToken)
{
// Create a linked token so we can trigger cancellation outside of this token's cancellation
_cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
// Store the task we're executing
_executingTask = ExecuteAsync(_cts.Token);
// If the task is completed then return it, otherwise it's running
return _executingTask.IsCompleted ? _executingTask : Task.CompletedTask;
}
public async Task StopAsync(CancellationToken cancellationToken)
{
// Stop called without start
if (_executingTask == null)
{
return;
}
// Signal cancellation to the executing method
_cts.Cancel();
// Wait until the task completes or the stop token triggers
await Task.WhenAny(_executingTask, Task.Delay(-1, cancellationToken));
// Throw if cancellation triggered
cancellationToken.ThrowIfCancellationRequested();
}
// Derived classes should override this and execute a long running method until
// cancellation is requested
protected abstract Task ExecuteAsync(CancellationToken cancellationToken);
}
then you can implement your abstract class:
public class DataRefreshService : HostedService
{
private readonly RandomStringProvider _randomStringProvider;
public DataRefreshService(RandomStringProvider randomStringProvider)
{
_randomStringProvider = randomStringProvider;
}
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
await _randomStringProvider.UpdateString(cancellationToken);
await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken);
}
}
}
,在您的设置中,您只需添加依赖项:
and in your setup you only have to add the dependency:
services.AddSingleton<IHostedService, DataRefreshService>();
RandomStringProvider
只是一个例子.你得到图片了:)
RandomStringProvider
is just an example. You get the picture :)
.net核心自动为您连接,就像一个护身符!保持rabbitmq连接打开的完美之选!
.net core wires this automatically for you, works like a charm! Perfect to keep a rabbitmq-connection open!
试一试!
这篇关于在自托管ASP.NET Core微服务中启动多个后台线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!