简体   繁体   中英

How to schedule task for a Worker service

I'm implementing asp.net core 3.1 project. 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. Now I could call the sms api and send some static data by it to the user. 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. 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 .

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.

The created services are then injected in IHostBuilder.ConfigureServices (Program.cs) with: services.AddHostedService<TimedHostedService>();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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