2012-09-06 37 views
1

我是ASP.NET MVC中的新成員。我熟悉Rails和PHP MVC FM等其他MVC框架。如何用asp.net mvc每天運行一次函數?

我需要在ASP.NET MVC內部同時運行一次函數一次 - 我該怎麼做?我想要這個函數來更新數據庫。

在Linux中,我可以將URL連接到Cron每天訪問一次的服務器,但我不知道在Windows中執行此操作的最佳方式。

+3

使用合適的工作的正確工具。在服務器上創建一個計劃任務來管理它。 – asawyer

+0

這聽起來像你正在尋找一個服務,或者這個效果。研究Windows任務調度程序或Windows服務。 –

+0

您無法保證將開始任務的工作進程在請求的時間處於活動狀態。也許它只是被回收?所以我同意asawyer ... –

回答

0

基本上你需要兩個的AppSettings添加到web.config文件:

<appSettings> 
    . 
    <add key="TimerStartTime" value="09:00:00 PM"/> 
    <add key="TimerIntervalInMilliseconds" value="3000000"/> 
</appSettings> 

然後,在Global.asax.cs中文件的修改和添加:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.Http; 
using System.Web.Mvc; 
using System.Web.Optimization; 
using System.Web.Routing; 
// Added the following for the timer related code 
using System.Diagnostics; 
using System.Timers; 
using System.Web.Configuration; 

namespace TestVSOnline01 
{ 
    public class MvcApplication : System.Web.HttpApplication 
    { 
     // Added this class visible variable to hold the timer interval so it's not gotten from the 
     // web.config file on each Elapsed event of the timer 
     private static double TimerIntervalInMilliseconds = 
      Convert.ToDouble(WebConfigurationManager.AppSettings["TimerIntervalInMilliseconds"]); 

     protected void Application_Start() 
     { 
      AreaRegistration.RegisterAllAreas(); 
      GlobalConfiguration.Configure(WebApiConfig.Register); 
      FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
      RouteConfig.RegisterRoutes(RouteTable.Routes); 
      BundleConfig.RegisterBundles(BundleTable.Bundles); 

      // Added the following within the Application_Start() procedure: 
      // ******************************************************************************************* 
      // The values used in this example will cause your processes to run sometime 
      // between 09:00:00 PM and 09:05:00 PM, with the timer Elapsed event being raised 
      // every 300000ms (5 minutes) 
      // 
      // The following AppSettings were added to Web.config: 
      // TimerStartTime 
      // TimerIntervalInMilliseconds 
      // You can use a simple text editor to change your start time and/or timer interval without 
      // having to modify your code, recompile, and republish it. 
      // 
      // The shorter the interval, then smaller the time window in which the processes will run, but 
      // the more frequently all of this code and event firing is happening. But you could set the 
      // interval to 1000ms and have you events run right at the time specified. 
      // 
      // !!! NOTE: The web.config file is not designed for constant updates. When an ASP.NET 
      // !!! application launches a watch is put on the web.config file. ASP.NET will detect if the 
      // !!! web.config changes while the application is running. When ASP.NET detects a change it 
      // !!! will spin up a new version of the application with the new settings in effect. Any in 
      // !!! process information, such as data kept in Session, Application, and Cache will be lost 
      // !!! (assuming session state is InProc and not using a state server or database). 
      // !!! (Source: http://odetocode.com/Articles/345.aspx) 
      // 
      // ******************************************************************************************* 

      // The Debug.WriteLine calls are for watching the progress in the Output Window 
      // in Visual Studio - Remove or comment out if you like 

      Debug.WriteLine(string.Concat("Application_Start Called: ", DateTime.Now.ToString())); 

      // This will raise the Elapsed event every 'x' millisceonds (whatever you set in the 
      // Web.Config file for the added TimerIntervalInMilliseconds AppSetting 
      Timer timer = new Timer(TimerIntervalInMilliseconds); 

      timer.Enabled = true; 

      // Setup Event Handler for Timer Elapsed Event 
      timer.Elapsed += new ElapsedEventHandler(timer_Elapsed); 

      timer.Start(); 
     } 

     // Added the following procedure: 
     static void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
     { 
      // Get the TimerStartTime web.config value 
      DateTime MyScheduledRunTime = DateTime.Parse(WebConfigurationManager.AppSettings["TimerStartTime"]); 

      // Get the current system time 
      DateTime CurrentSystemTime = DateTime.Now; 

      Debug.WriteLine(string.Concat("Timer Event Handler Called: ", CurrentSystemTime.ToString())); 

      // This makes sure your code will only run once within the time frame of (Start Time) to 
      // (Start Time+Interval). The timer's interval and this (Start Time+Interval) must stay in sync 
      // or your code may not run, could run once, or may run multiple times per day. 
      DateTime LatestRunTime = MyScheduledRunTime.AddMilliseconds(TimerIntervalInMilliseconds); 

      // If within the (Start Time) to (Start Time+Interval) time frame - run the processes 
      if ((CurrentSystemTime.CompareTo(MyScheduledRunTime) >= 0) && (CurrentSystemTime.CompareTo(LatestRunTime) <= 0)) 
      {     
       Debug.WriteLine(String.Concat("Timer Event Handling MyScheduledRunTime Actions: ", DateTime.Now.ToString())); 
       // RUN YOUR PROCESSES HERE 
      } 
     } 
    } 
} 

清理,這是很簡單。下面的代碼是您需要添加到文件的Global.asax.cs什麼只是一個簡化版本(不要忘了添加web.config的AppSettings仍然):

// Added the following for the timer related code 
using System.Diagnostics; // Can remove this reference if you remove all the Debug.Writeline entries 
using System.Timers; 
using System.Web.Configuration; 

// Add the following to the top of the main class, outside of any subroutines: 
private static double TimerIntervalInMilliseconds = Convert.ToDouble(WebConfigurationManager.AppSettings["TimerIntervalInMilliseconds"]); 

// Add the following to the end of the Application_Start() subroutine: 
Timer timer = new Timer(TimerIntervalInMilliseconds); 
timer.Enabled = true; 
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed); 
timer.Start(); 

// Added the following procedure: 
static void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
    {  
     DateTime MyScheduledRunTime = DateTime.Parse(WebConfigurationManager.AppSettings["TimerStartTime"]); 
     DateTime CurrentSystemTime = DateTime.Now; 
     DateTime LatestRunTime = MyScheduledRunTime.AddMilliseconds(TimerIntervalInMilliseconds); 
     if ((CurrentSystemTime.CompareTo(MyScheduledRunTime) >= 0) && (CurrentSystemTime.CompareTo(LatestRunTime) <= 0)) 
     {     
      // RUN YOUR PROCESSES HERE 
     } 
    }