如何为 Worker 服务安排任务

时间:2021-05-07 10:20:37

标签: c# asp.net-core

我正在实施 asp.net core 3.1 项目。我正在使用一个 Worker 服务,它应该每天从 SQL 服务器表中读取一些数据,并调用一个应该发送短信的 api,短信内容应该是从 sql server 读取的那些数据。现在我可以调用 sms api 并通过它向用户发送一些静态数据。问题是,我定义了 api 应该每 5 秒调用一次,但它只向使用发送 1 次短信。如果有人告诉我如何解决这个问题,我将不胜感激。以下是我尝试过的:

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
        }

        }
    }
}

发送短信服务

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();

            }
        }

    }
}

报告

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

}

程序

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));
                

            });
}

1 个答案:

答案 0 :(得分:0)

在这种情况下,您可以使用 Timed background task 参见 timed-background-tasks

在您的情况下,您需要其中两个。它们根据您在 Timer 方法中的 StartAsync 参数进行调度,您不必将它们称为显式。

然后将创建的服务注入到 IHostBuilder.ConfigureServices (Program.cs) 中:services.AddHostedService<TimedHostedService>();

相关问题