Wednesday, December 4, 2013

ASP.NET Tricky Scheduler Without Service

ASP.NET Scheduler Without Service:
ShortIntro:How can we run scheduled jobs in ASP.NET without requiring a Windows Service to be installed on the server? Very often, we need to run some maintenance tasks or scheduled tasks like sending reminder emails to users from our websites. This can only be achieved using a Windows Service. ASP.NET being stateless provides no support to run code continuously or to run code at a scheduled time. As a result, we have to make our own Windows Services to run scheduled jobs. But in a shared hosted environment, we do not always have the luxury to deploy our own Windows Service to our hosting provider's web server. We either have to buy a dedicated server which is very costly, or sacrifice such features in our web solution. I will show you the tricky way to run scheduled jobs using pure ASP.NET without requiring any Windows Service. This solution runs on any hosting service providing just ASP.NET hosting. As a result, you can have the scheduled job feature in your ASP.NET web projects without buying dedicated servers.

Let Us start with the code in a simple & sweet manner.

Step:1

        private const string DummyCacheItemKey = "HipHipHurray";
        private const string DummyPageUrl = "http://localhost:8001/WebsiteName/DummyPageSchedular.aspx";
        //this DummyPage Url is Used to Alive the Cache


         void Application_Start(object sender, EventArgs e)
        {
           RegisterCacheEntry();    //Registering the Cache
        }
        private bool RegisterCacheEntry()
        {
            //This Method Register Cache
            if (null != HttpContext.Current.Cache[DummyCacheItemKey]) return false;HttpContext.Current.Cache.Add(DummyCacheItemKey, "Test", null, DateTime.MaxValue,     TimeSpan.FromMinutes(1), CacheItemPriority.Normal, new CacheItemRemovedCallback(CacheItemRemovedCallback));

            //the minimum time cache expires is 2minutes,when it expires it calls CacheItemRemovedCallback()
            return true;
        }
     
 
Step:2//CacheItemRemovedCallback Method gets Called After Every 2 minuts
        //Now What to Think Perform Your Task here I have written my code to be run at scheduled intervals in  in one .cs class so I am calling that  Method(PerformSchedularTasks())Here


        public void CacheItemRemovedCallback(string key,object value,CacheItemRemovedReason reason)
        {
            try
            {
                PerformSchedularTasks(); // Do the scheduled tasks
                //After Performing Your Tasks,Your Duty is to Register the Cache again inorder to make Call to this Method Again..Right..??
                //So,Now The Question is How to Do that,It Can be Done by Downloading a Dummy Page with WebClient Class and We are Doing it in HitPage Function
                //More Explantion:
                /*Whenever the cache item expires, we get a callback and the item is gone from the cache. So, we no longer get any callback in future. In order to have a continuous supply of callback, we need to store an item in cache again upon expiration. This seems quite easy; we can call the RegisterCacheEntry function shown above from the callback function, can't we? It does not work. When the callback method fires, there is no HttpContext available. The HttpContext object is only available when a request is being processed. As the callback is fired from the web server behind the scene, there is no request being processed and thus no HttpContext is available. As a result, you cannot get access to the Cache object from the callback function.                The solution is, we need to simulate a request. We can make a dummy call to a dummy webpage by utilizing the WebClient class in the .NET Framework. When the dummy page is being executed, we can get hold of the HttpContext and then register the callback item again.*/

                HitPage();//Calling the Method to Download the Dummy Page
            }
            catch
            {
                //This Code I have written to make my code to be perfect and Cache will be registered even if any exception Occured in your task code written in PerformSchedularTasks() method

                HitPage();
            }
        }
     
        private void HitPage()
        {
            try
            {
                WebClient client = new WebClient();
                client.DownloadData(DummyPageUrl);//It Calls Dummy Page.If Dummy Page is Called then   Application_BeginRequest Executes
            }
            catch(Exception ex)
            {
            Logger.Log("Cache is not Registered:"+DateTime.Now.ToString()+" due to Exception "+ex.Message.ToString()+"");//Noting Down the Exception in Log File
            }
        }
        //Whenever the dummy page executes, the Application_BeginRequest method gets called. There, we can check whether this is a dummy page request or not,and Register the Cache to Maintain Cyclic Process
    

      

Step:3
         protected void Application_BeginRequest(Object sender, EventArgs e)
        {
            // If the dummy page is hit, then it means we want to add another item  in cache
            if (HttpContext.Current.Request.Url.ToString() == DummyPageUrl)
            {
                // Add the item in cache and  PerformSchedularTasks on Expire
                RegisterCacheEntry();
            }
        }


-----------------------------------------------------------------------------------
How Does Scheular Work?   

1)In First, on Application_Start, we have registered a cache item that will expire in two minutes.Please note, the minimum duration you can set for expiring a callback is two minutes.The onRemoveCallback is a delegate to a method which is called whenever a cache item expires.In that method, we can do anything we want.
2)In onRemoveCallback method we are Performing the Task and Registering the Cache Again in HitPage()
3)The HitPage function makes a call to a dummy page,Whenever the dummy page executes,the Application_BeginRequest method gets called.
4)In Application_BeginRequestwe can check whether this is a dummy page request or not,And Registering the Cache
-->This Cyclic Process Repeats Again From Step 1 - Written--->


------------------------------------------------------------------------------------
 
             

2 comments:

Unknown said...

Friends Scheduler implementation described above has tested and working fine..let me know If you have any doubts or facing problem to implement

Unknown said...

For Code mail me @ mail2mohdilyas@gmail.com,I will send you running code to include