简体   繁体   English

如何为 Worker 服务安排任务

[英]How to schedule task for a Worker service

I'm implementing asp.net core 3.1 project.我正在实施 asp.net 核心 3.1 项目。 I'm using a Worker service which should read every day some data from SQL server table and the call an api which should send an sms and the sms content should be those data which were read from sql server.我正在使用一个 Worker 服务,它应该每天从 SQL 服务器表中读取一些数据,并调用一个 api 应该发送一条短信,短信内容应该是从 ZAC5C74B64B4B8352EF2F11 服务器读取的那些数据。 Now I could call the sms api and send some static data by it to the user.现在我可以调用短信 api 并通过它向用户发送一些 static 数据。 The problem is although, I defined that the api should be called each 5 seconds but it just send the sms 1 time to the use.问题是,虽然我定义了 api 应该每 5 秒调用一次,但它只发送 1 次短信以供使用。 I appreciate if anyone tells me how I can fix this.如果有人告诉我如何解决这个问题,我将不胜感激。 Here below is what I have tried:下面是我尝试过的:

public class Worker : BackgroundService, IHostedService, ISendingSMS
{
    private readonly ILogger<Worker> _logger;


    private MarketsContext _context;


    public IServiceScopeFactory _serviceScopeFactory;
    //---------------------------------------------------
    public Report report { get; set; }
    private MsgContent msgContent;
    //---------------------------------------------------
    public Worker(IServiceScopeFactory serviceScopeFactory)
    {
   
        _serviceScopeFactory = serviceScopeFactory;

    }

    //---------------------------------------------------------------------------------------
    public async Task GetReport()
    {

        IQueryable<Report> reportData = _context.Report.Select(x => new Report
        {
            ReportDate = x.ReportDate,
            TotalMarkets = x.TotalMarkets,
           
        })/*.FirstOrDefault()*/;

        report = await reportData.AsNoTracking().FirstOrDefaultAsync();
    }
    //-------------------------------------------------------------------------------
    public override async Task StartAsync(CancellationToken cancellationToken)
    {
        // DO YOUR STUFF HERE
        await base.StartAsync(cancellationToken);
    }

    public override async Task StopAsync(CancellationToken cancellationToken)
    {
        // DO YOUR STUFF HERE
        await base.StopAsync(cancellationToken);
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {

        using (var scope = _serviceScopeFactory.CreateScope())
        {
            var dbContext = scope.ServiceProvider.GetRequiredService<MarketsContext>();

            var _smssend = scope.ServiceProvider.GetRequiredService<SendingSMSService>();

            _context = dbContext;

            await GetReport();


            var message = new MsgContent
            {
                Username = "cse.etsg",
                Password = "wrwe",
                From = "4500000",
                To = "+429124203243",
                Message = report.ReportDate + "" + + report.TotalMarkets
            };


            _smssend.sendSMS(message);
           
            await Task.Delay(120000, stoppingToken);

            //Do your stuff
        }

        }
    }
}

SendingSMSService发送短信服务

public class SendingSMSService /*: ISendingSMS*/
{

    public Report report { get; set; }


    // Here this method calls sms api sccessfully

    public async void sendSMS(MsgContent message)
    {

    

        using (var client = new HttpClient())
        {

            var myContent = JsonConvert.SerializeObject(message);
            var buffer = System.Text.Encoding.UTF8.GetBytes(myContent);
            var byteContent = new ByteArrayContent(buffer);
            byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");

            using (var result = client.PostAsync("https://api/SendSMS", byteContent).Result)
            {
                string Response = await result.Content.ReadAsStringAsync();

            }
        }

    }
}

Report报告

public partial class Report
{
    public int Id { get; set; }
    public string ReportDate { get; set; }
    public int? TotalMarkets { get; set; }

}

Program程序

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
         .UseWindowsService()
            .ConfigureServices((hostContext, services) =>
            {

                var configuration = hostContext.Configuration;

                services.AddHostedService<Worker>();
                //------------------------------------------------------------------------------
                services.AddScoped<SendingSMSService>();

                var connection = hostContext.Configuration.GetConnectionString("Markets");
                var optionsBuilder = new DbContextOptionsBuilder<MarketsContext>();
                optionsBuilder.UseSqlServer(connection);
                services.AddScoped<MarketsContext>(s => new MarketsContext(optionsBuilder.Options));
                

            });
}

In this scenario you can use a Timed background task see timed-background-tasks .在这种情况下,您可以使用Timed background task ,请参阅timed-background-tasks

In your case you would need two of them.在您的情况下,您将需要其中两个。 They are sheduled according to your parameters of the Timer in the StartAsync method, you not have to call them explicit.它们根据您在StartAsync方法中的Timer参数进行调度,您不必显式调用它们。

The created services are then injected in IHostBuilder.ConfigureServices (Program.cs) with: services.AddHostedService<TimedHostedService>();然后将创建的服务注入到 IHostBuilder.ConfigureServices (Program.cs) 中: services.AddHostedService<TimedHostedService>();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM