Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何创建一个在给定时间段内运行函数的后台服务?使用C#(asp.net core 3.1.1)_C#_Asp.net Core_Background Service - Fatal编程技术网

如何创建一个在给定时间段内运行函数的后台服务?使用C#(asp.net core 3.1.1)

如何创建一个在给定时间段内运行函数的后台服务?使用C#(asp.net core 3.1.1),c#,asp.net-core,background-service,C#,Asp.net Core,Background Service,我正在尝试每隔指定的时间间隔调用一个函数,因为我使用后台服务,下面是我所做的: 这是警报控制器,我在这里有以下功能: public class AlertingController : ControllerBase { private readonly DatabaseContext _context; private readonly IMapper _mapper; public AlertingController(DatabaseContext context,

我正在尝试每隔指定的时间间隔调用一个函数,因为我使用后台服务,下面是我所做的: 这是警报控制器,我在这里有以下功能:

public class AlertingController : ControllerBase
{
    private readonly DatabaseContext _context;
    private readonly IMapper _mapper;

    public AlertingController(DatabaseContext context, IMapper mapper)
    {
        _context = context ?? throw new ArgumentNullException(nameof(context));
        _mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
    }
    public AlertingController()
    {

    }
//function that adds in the DB
    public async Task<AlertingResponse> GetAlertingToDB()
    {
        AlertingResponse dataGet;

        using (var httpClient = new HttpClient())
        {
            using (var response = await httpClient
                .GetAsync(MetricApiLink))
            {
                string apiResponse = await response.Content.ReadAsStringAsync();
                dataGet = JsonConvert.DeserializeObject<AlertingResponse>(apiResponse);
            }
        }
        if (dataGet.data.alerts != null || dataGet.data.alerts.Count > 0)
        {
            foreach (var alert in dataGet.data.alerts)
            {
                CreateAlertQuery QueryAlert = new CreateAlertQuery();
                QueryAlert.Name = alert.labels.alertname;
                QueryAlert.Instance = alert.labels.instance;
                QueryAlert.Serverity = alert.labels.severity;
                QueryAlert.Summary = alert.annotations.summary;
                QueryAlert.State = alert.state;
                QueryAlert.ActiveAt = alert.activeAt;
                var _Alert = _mapper.Map<AlertingDataModel>(QueryAlert);
                _context.Alertings.Add(_Alert);
                await _context.SaveChangesAsync();
            }
        }

        return null;
    }
}
我还创建了将使用我的服务并在后台运行的类:

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
                    .GetRequiredService<IScopedAlertingService>();

            await scopedProcessingService.DoWork(stoppingToken);
        }
    }

    public override async Task StopAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation(
            "Consume Scoped Service Hosted Service is stopping.");

        await Task.CompletedTask;
    }
}
公共类ConsumeScopedService HostedService:BackgroundService
{
专用只读ILogger\u记录器;
公共消费范围服务托管服务(IServiceProvider services,
ILogger(记录器)
{
服务=服务;
_记录器=记录器;
}
公共IServiceProvider服务{get;}
受保护的覆盖异步任务ExecuteAsync(CancellationToken stoppingToken)
{
_logger.login信息(
“使用作用域服务托管服务运行。”);
等待工作(停止工作);
}
专用异步任务DoWork(CancellationToken stoppingToken)
{
_logger.login信息(
“使用作用域服务托管服务正在工作。”);
使用(var scope=Services.CreateScope())
{
var scopedProcessingService=
scope.ServiceProvider
.GetRequiredService();
等待范围处理服务。停止工作(停止工作);
}
}
公共覆盖异步任务StopAsync(CancellationToken stoppingToken)
{
_logger.login信息(
“使用作用域服务承载的服务正在停止。”);
等待任务。完成任务;
}
}
我在Startup类中注入了依赖项,并添加了托管服务:

        services.AddHostedService<ConsumeScopedServiceHostedService>();
        services.AddScoped<IScopedAlertingService, ScopedAlertingService>();
services.AddHostedService();
services.addScope();
在调用
GetAlertingToDB()
函数之前,这些函数一直工作正常,但它不工作


任何帮助都会很好,谢谢大家:)

Hangfire Recurreng Job将是您案例的一个选择。你可以在这里查一下。
使用它的好处是:您有一个仪表板来检查何时启动任务以及任务的结果。

有几个选项可供选择

请阅读Microsoft文档中的以下链接,其中有几个关于如何在.NET Core和ASP.NET Core中执行此操作的示例:

它被称为工人服务

您基本上实现了两个接口:IHostedService和IDisposable

然后在ConfigureServices方法中的Startup类中注册服务,如下所示:

services.AddHostedService<MyCoolWorkerServiceClass>();
services.AddHostedService();
暂时

最后一个建议。该示例使用System.Threading.Timer。。。但我认为最好使用System.Timers.Timer和AutoReset=false

原因是为了避免服务的重复运行。完成跑步后,再次启动计时器


但这一切都取决于您想要实现什么。

我个人会重新安排您的解决方案,这样您的后台服务就不需要创建
控制器了。相反,如果您仍然需要它,控制器应该调用您的
ScopedAlertingService
,在那里工作执行一次。您的后台服务可以通过
等待Task.Delay()
永远循环

公共类ScopedAlertingService:IScopedAlertingService
{
公共异步任务DoWork(CancellationToken stoppingToken)
{
//将AlertingController.GetAlertingToDB的内容移到此处
}
}
公共类ConsumeScopedService HostedService:BackgroundService
{
私人只读阅读器ViceProvider服务;
公共消费范围服务托管服务(IServiceProvider服务)
{
_服务=服务;
}
受保护的覆盖异步任务ExecuteAsync(CancellationToken stoppingToken)
{
同时(!stoppingToken.IsCancellationRequested)
{
等待任务。延迟(10000,停止待命);
使用(var scope=\u services.CreateScope())
{
var scopedProcessingService=
scope.ServiceProvider
.GetRequiredService();
等待范围处理服务。停止工作(停止工作);
}
}
}
}

正如我在他们的文档中看到的那样,我们可以在API中运行后台服务,我还观看了youtube上的一个教程,其中有人通过修剪vdeios等创建了一个项目。。。使用排队的后台服务,单独运行它们可能是个好主意,但我更喜欢在应用程序启动时运行服务,在应用程序启动时关闭服务shuts@Hasagiii:当然,您可以在proc中并行运行后台服务,但是你不能直接从后台服务打电话给控制器,好吗?谢谢:)改用定时后台任务。我在asp.net core中添加了一个带有此示例的链接。HangFire基于asp.net框架,我使用.net core进行多平台,我知道有很多库,如quartz net等。。但我更喜欢使用托管服务:)我正在使用hangfire for.netcore,它部署在ubuntu服务器上,运行良好。你有没有检查过hangfire页面,它有一句话:“在.NET和.NET核心应用程序中执行后台处理的简单方法”是的,非常感谢很多人,因为现在我已经管理了它的功能,你的想法很好,我将在将来使用它以满足某些需要:DI保留了代码原样,我刚刚将函数移动到
DoWork()
方法,现在它工作正常,我将尝试以另一种方式再次执行:)是的@Jonathan,我看到了示例,尝试按照他们说的做,但我无法调用该函数,我想每次我需要映射器和DB上下文时,我都必须对它们进行维护?@Hasagiii是的,但不是创建一个“Sco”
services.AddHostedService<MyCoolWorkerServiceClass>();