c# - 如何为 Worker 服务安排任务
问题描述
我正在实施 asp.net core 3.1 项目。我正在使用一个 Worker 服务,它应该每天从 SQL server 表中读取一些数据,并调用一个应该发送 sms 的 api,sms 内容应该是从 sql server 读取的那些数据。现在我可以调用 sms api 并通过它向用户发送一些静态数据。问题是,虽然我定义应该每 5 秒调用一次 api,但它只是发送 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));
});
}
解决方案
在这种情况下,您可以使用Timed background task
see timed-background-tasks。
在您的情况下,您将需要其中两个。它们是根据您Timer
在StartAsync
方法中的参数进行调度的,您不必显式调用它们。
然后将创建的服务注入到 IHostBuilder.ConfigureServices (Program.cs) 中:services.AddHostedService<TimedHostedService>();
推荐阅读
- java - Mono.toFuture() 是否阻塞?
- angular - 有没有办法使用 Angular 4.x 获取 ng2-materialize 自动完成的选定选项?
- java - requireThat() 和 requireSingleCommand() 未定义
- python - 当我使用 twilio API 时,如何在 AWS Lambda 函数中使用 python 修复超时错误
- matter.js - 具有约束实体的 Matter.js 碰撞过滤器
- python - Pandas Datetime:基于时间滞后的聚合
- r - Biomod2 生成的伪缺失
- wso2 - 上下文不存在。可能是由于离开登录页面超过一分钟后出现无效缓存错误
- excel - VBA:转到 IE 站点并按元素打勾
- amazon-web-services - 如何使用来自 ACM 的 AWS 证书使用亚马逊 EC2 从端口 80 重定向到 443?