在自托管ASP.NET Core微服务中启动多个后台线程 [英] Start multiple background threads inside Self Hosted ASP.NET Core Microservice

查看:1237
本文介绍了在自托管ASP.NET Core微服务中启动多个后台线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在哪里可以在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆