Making your ASP.NET application work as a service.



Now this post by the title already says is controversial or a hack, I take the second one, what that means is I’m recommending not to use the code in the post as anything plan to go close to production, this is just a little fun with code.

Most of the time, in ASP.NET you find yourself that when designing an application, you need to think about a Windows Service to complete a task without any user interaction. In the ASP.NET architecture, the user loads a page and code behind get executed, then results from the code will be display to the user. Now when the application needs to, for example, download the twitter public timeline, you cannot expect that you’ll have so many users to execute server side methods to do just that. When nobody is making requests, your ASP.NET application is not doing anything, how to make it do something?

So there is an state object in .NET called the Cache class. That class has a great delegate to expire the content stored in that object.

   1: public class MyDateTime
   2:     {
   3:         public DateTime datetime
   4:         { get; set; }
   5:  
   6:         public HttpContext context
   7:         { get; set; }
   8:     }
   9:  
  10:     public class MyCache
  11:     {
  12:         static List<MyDateTime> datetimeList = null;
  13:         static string cacheName = "test";
  14:         static CacheItemRemovedCallback onRemove = null;
  15:  
  16:         public static void InsertNewCache(HttpContext context, List<MyDateTime> oldDatetimeList)
  17:         {
  18:             // First time create the collection, otherwise retrive it.
  19:             if (oldDatetimeList != null)
  20:             {
  21:                 datetimeList = oldDatetimeList;
  22:             }
  23:             else if (context.Cache[cacheName] == null)
  24:                 datetimeList = new List<MyDateTime>();
  25:             else
  26:                 return;
  27:             
  28:             MyDateTime myItem = new MyDateTime()
  29:             {
  30:                 datetime = DateTime.Now,
  31:                 context = context
  32:             };
  33:  
  34:             datetimeList.Add(myItem);
  35:  
  36:             onRemove = new CacheItemRemovedCallback(RemovedCallback);
  37:  
  38:             DateTime dtExpiration = DateTime.UtcNow.AddSeconds(10);
  39:             
  40:             context.Cache.Add(cacheName,
  41:                                     datetimeList,
  42:                                     null,
  43:                                     dtExpiration,
  44:                                     System.Web.Caching.Cache.NoSlidingExpiration,
  45:                                     System.Web.Caching.CacheItemPriority.High,
  46:                                     onRemove);
  47:         }
  48:  
  49:         public static void RemovedCallback(String k, Object v, CacheItemRemovedReason r)
  50:         {
  51:             List<MyDateTime> retrievedCache = v as List<MyDateTime>;
  52:             InsertNewCache(retrievedCache[retrievedCache.Count-1].context, retrievedCache);
  53:         }
  54:     }

 

Create a webpage to call once to start the process.

   1: public partial class _Default : System.Web.UI.Page
   2:     {
   3:         protected void Page_Load(object sender, EventArgs e)
   4:         {
   5:             if (Cache["test"] != null)
   6:             {
   7:                 List<MyDateTime> dtList = Cache["test"] as List<MyDateTime>;
   8:                 foreach (MyDateTime dt in dtList)
   9:                 {
  10:                     Response.Write(dt.datetime.ToString() + "<BR/>");
  11:                 }
  12:             }
  13:             else
  14:             {
  15:                 MyCache.InsertNewCache(HttpContext.Current, null);
  16:             }
  17:         }
  18:     }

 

The results:

1:12:48 PM
1:13:00 PM
1:13:11 PM
1:13:40 PM
1:13:52 PM
1:14:15 PM
1:14:28 PM

Disclaimer: This is horrible code, this is to proof a concept, not to go live with anything to production with something like that, I just want to show, how the Cache object calls itself without a HttpContext and can run as long as IIS does not unload the Application Pool. As you can see the time is pretty variable, so there isn’t a warranty of the time span.

Now to keep IIS from unloading your application, you could on the CallBack event make a request to the application from within the application, not that will completely avoid that problem, yet will delay it.

Cheers

Al

1 Comment

  • Fun stuff! It feels like a self-calling function in JavaScript! Another hack like this would be to use the application_start event in the global.asax to kick off the process. Or you could setup a timer with a callback within the application_start event. Probably not a good idea either ;)

Comments have been disabled for this content.