ASP.NET MVC Web应用程序反复访问和修改数据库的最佳实践

时间:2015-09-23 21:17:31

标签: c# asp.net asp.net-mvc entity-framework azure-webjobs

我的应用程序用户有一个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更可取,因为我最多可以每小时运行一次。

2 个答案:

答案 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界面来管理您的工作。