我的应用程序用户有一个balance属性,只要他们已激活服务就需要更新。到目前为止,更新功能使用每小时运行一次的.net webjob(对于共享或基本订阅,webjobs最多可以每小时运行一次)。
是否有更好的解决方案来实施平衡更新功能?我还考虑通过以下方式在Application_Start()
上执行此操作:
public class MvcApplication : System.Web.HttpApplication
{
private ApplicationDbContext db = new ApplicationDbContext();
private PaymentsController paymentsController = new PaymentsController();
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
Timer tmr = new Timer();
tmr.Interval = 60000; //1 minute
tmr.Elapsed += updateUsersBalance;
tmr.Start();
}
private void updateUsersBalance(Object source, System.Timers.ElapsedEventArgs e)
{
var users = db.Users.ToList();
foreach (var user in users)
{
user.balance -= 1;
db.Entry(user).State = EntityState.Modified;
}
db.SaveChanges(); //save updated balances
}
这是每分钟更新天平的可靠机制吗?是否可以在Global.cs
文件中引用数据库和控制器?
(不考虑计时器的精确度)
在我的情况下,这种情况比webjob更可取,因为我最多可以每小时运行一次。
答案 0 :(得分:1)
不,这本身不是一种可靠的方法。 IIS可能会关闭应用程序池,因此您的循环将无法运行。你可以通过设置ASP.NET Auto-Start来解决这个问题(在Azure中有一个" Always On"在配置页面中切换以启用它)但是真正的工作跑步者可能是更好的选择(除了ASP.NET Auto-Start之外。也许结帐Hangfire(这是我们目前正在使用的)或Quartz.net
答案 1 :(得分:1)
@nest我不明白你的架构究竟是什么,但我认为我理解你的需要。
每分钟更新您的余额是虚拟的,请考虑一下:“如果没有人阅读它,为什么需要更新余额?”
考虑到这一点,您可以断言只要有人访问您的余额就会更新。这样可以节省处理资源。所以你不需要为每一分钟运行这个过程而烦恼,你需要每次运行都有变化,并且为了冗余,你可以在访问之前重新计算。
那说你可以使用Job Scheduler来计算余额,我建议Hangfire,每当有人改变值时强制Job运行,并且还安排在一个间隔上运行或强制运行,如果该间隔是在某人访问时没有遇到。
当然,这样您就需要更改为Web角色,主要是因为Hangfire有一个Web界面来管理您的工作。