Click here to Skip to main content
15,880,796 members
Articles / Desktop Programming / Windows Forms
Article

Using Cache in Your WinForms Applications

Rate me:
Please Sign up or sign in to vote.
4.81/5 (33 votes)
5 Dec 20042 min read 188.8K   2.1K   84   28
The article talks about using the System.Web.Caching.Cache object in WinForms applications.

Introduction

I am working on a WinForms application where I need to cache some information for a period of time. There are a number of ways to accomplish this. For instance, one can use the Caching Application Block from Microsoft. However, I came across a Microsoft Knowledge Base Article that covers a problem with the Caching Application Block. Inconsistencies can occur when multiple threads attempt to update the same cache item in a short time. As a workaround, the article suggests using another caching mechanism such as the ASP.NET cache.

This got me thinking. Is it possible to use the Microsoft ASP.NET cache in a WinForms application? So, I wrote a sample app to see if it is possible.

The Cache Object

To clarify what I mean by ASP.NET cache, I am referring specifically to the System.Web.Caching.Cache object. I am not referring to page cache, application cache, etc. In my sample, I want to see if the Cache object itself can be used in a .NET WinForms application.

Getting Started

I start by creating a new WinForms application in Visual Studio .NET. As I always do, I deleted the Form1.cs created by VS.NET and I added a new class called AppMain.cs. I prefer using AppMain to define the application entry point instead of defining the entry point as part of a form. Next, I add the System.Web.dll to my project reference list. This assembly is needed to reference the Cache object.

With the AppMain class in place, I added code to start the HttpRuntime. The HttpRuntime class provides a set of ASP.NET run-time services to the current application. This includes the Cache object that is used in this sample. And because I am only interested in accessing the Cache object within my sample application, I will expose a public property from the AppMain class called Cache. This allows other classes within my application to access the cache. Here is the code for AppMain.cs:

C#
using System;
using System.Threading;
using System.Web;
using System.Web.Caching;
using System.Windows.Forms;

namespace CacheSample
{
   public class AppMain
   {
      private static HttpRuntime _httpRuntime;

      public static Cache Cache
      {
         get
         {
            EnsureHttpRuntime();
            return HttpRuntime.Cache;
         }
      }

      [STAThread]
      static void Main() 
      {
         Application.Run(new Form1());
      }
      
      private static void EnsureHttpRuntime()
      {
         if( null == _httpRuntime )
         {
            try
            {
               Monitor.Enter( typeof( AppMain ) );
               if( null == _httpRuntime )
               {
                  // Create an Http Content to give us access to the cache.
                  _httpRuntime = new HttpRuntime();
               }
            }
            finally
            {
               Monitor.Exit( typeof( AppMain ) );
            }
         }
      }
   }
}

Using the Cache

Since this is nothing more than a sample application, I will keep the requirements simple. The application will include a single Form. On this form, the user can enter any text to be inserted into the cache. There is also a button to retrieve the value from the cache. A default message is displayed if the cache is empty.

Sample Image

Here is the code for the form:

C#
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Web.Caching;
using System.Data;

namespace CacheSample
{
   public class Form1 : System.Windows.Forms.Form
   {
      private System.Windows.Forms.Label label1;
      private System.Windows.Forms.Label label2;
      private System.Windows.Forms.TextBox txtValueToPutInCache;
      private System.Windows.Forms.TextBox txtValueInCache;
      private System.Windows.Forms.Button btnPutInCache;
      private System.Windows.Forms.Button btnGetFromButton;
      
      private const string CACHE_KEY = "APPCACHEKEY";
      
      /// <summary>
      /// Required designer variable.
      /// </summary>
      private System.ComponentModel.Container components = null;
      
      public Form1()
      {
         //
         // Required for Windows Form Designer support
         //
         InitializeComponent();
         
         //
         // TODO: Add any constructor code after InitializeComponent call
         //
      }
      
      /// <summary>
      /// Clean up any resources being used.
      /// </summary>
      protected override void Dispose( bool disposing )
      {
         if( disposing )
         {
            if (components != null) 
            {
               components.Dispose();
            }
         }
         base.Dispose( disposing );
      }

      #region Windows Form Designer generated code
      /// <summary>
      /// Required method for Designer support - do not modify
      /// the contents of this method with the code editor.
      /// </summary>
      private void InitializeComponent()
      {
         this.label1 = new System.Windows.Forms.Label();
         this.label2 = new System.Windows.Forms.Label();
         this.txtValueToPutInCache = new System.Windows.Forms.TextBox();
         this.txtValueInCache = new System.Windows.Forms.TextBox();
         this.btnPutInCache = new System.Windows.Forms.Button();
         this.btnGetFromButton = new System.Windows.Forms.Button();
         this.SuspendLayout();
         // 
         // label1
         // 
         this.label1.AutoSize = true;
         this.label1.Location = new System.Drawing.Point(8, 16);
         this.label1.Name = "label1";
         this.label1.Size = new System.Drawing.Size(113, 16);
         this.label1.TabIndex = 0;
         this.label1.Text = "Value to put in cache:";
         // 
         // label2
         // 
         this.label2.AutoSize = true;
         this.label2.Location = new System.Drawing.Point(8, 40);
         this.label2.Name = "label2";
         this.label2.Size = new System.Drawing.Size(95, 16);
         this.label2.TabIndex = 1;
         this.label2.Text = "Value from cache:";
         // 
         // txtValueToPutInCache
         // 
         this.txtValueToPutInCache.Location = new System.Drawing.Point(128, 16);
         this.txtValueToPutInCache.Name = "txtValueToPutInCache";
         this.txtValueToPutInCache.Size = new System.Drawing.Size(200, 20);
         this.txtValueToPutInCache.TabIndex = 2;
         this.txtValueToPutInCache.Text = "";
         // 
         // txtValueInCache
         // 
         this.txtValueInCache.Location = new System.Drawing.Point(128, 40);
         this.txtValueInCache.Name = "txtValueInCache";
         this.txtValueInCache.ReadOnly = true;
         this.txtValueInCache.Size = new System.Drawing.Size(200, 20);
         this.txtValueInCache.TabIndex = 3;
         this.txtValueInCache.Text = "";
         // 
         // btnPutInCache
         // 
         this.btnPutInCache.Location = new System.Drawing.Point(352, 16);
         this.btnPutInCache.Name = "btnPutInCache";
         this.btnPutInCache.Size = new System.Drawing.Size(104, 23);
         this.btnPutInCache.TabIndex = 4;
         this.btnPutInCache.Text = "Put in Cache";
         this.btnPutInCache.Click += 
              new System.EventHandler(this.btnPutInCache_Click);
         // 
         // btnGetFromButton
         // 
         this.btnGetFromButton.Location = new System.Drawing.Point(352, 40);
         this.btnGetFromButton.Name = "btnGetFromButton";
         this.btnGetFromButton.Size = new System.Drawing.Size(104, 23);
         this.btnGetFromButton.TabIndex = 5;
         this.btnGetFromButton.Text = "Get from Cache";
         this.btnGetFromButton.Click += 
              new System.EventHandler(this.btnGetFromButton_Click);
         // 
         // Form1
         // 
         this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
         this.ClientSize = new System.Drawing.Size(488, 133);
         this.Controls.Add(this.btnGetFromButton);
         this.Controls.Add(this.btnPutInCache);
         this.Controls.Add(this.txtValueInCache);
         this.Controls.Add(this.txtValueToPutInCache);
         this.Controls.Add(this.label2);
         this.Controls.Add(this.label1);
         this.Name = "Form1";
         this.Text = "Form1";
         this.ResumeLayout(false);
      }
      #endregion

      private void btnPutInCache_Click(object sender, System.EventArgs e)
      {
         AppMain.Cache.Insert( 
            CACHE_KEY, 
            txtValueToPutInCache.Text, 
            null, 
            Cache.NoAbsoluteExpiration,
            TimeSpan.FromSeconds( 60 ) );
      }

      private void btnGetFromButton_Click(object sender, System.EventArgs e)
      {
         string value;
         value = AppMain.Cache[ CACHE_KEY ] as string;
         if( null == value )
         {
            value = "[No value in the cache.]";
         }
         txtValueInCache.Text = value;
      }
    }
}

Conclusion

As you can see from this code, once the application starts the HttpRuntime, the Cache object can be used. As this sample shows, not only can ASP.NET applications use the Cache object but WinForms applications can take advantage of the rich features provided by this .NET Framework class.

References

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior)
United States United States
Kirby Turner, founder of White Peak Software Inc (www.whitepeaksoftware.com), has been in the IT space producing and delivering quality custom solutions since 1985. He has worked with a variety of technologies ranging from proprietary development languages running on mini-computers to the latest COM+ and .NET technologies for the Microsoft Windows platform. Kirby became a Microsoft Certified Professional in 1995 and most recently became a Charter Member Microsoft Certified Application Developer (MCAD) as well as an Early Achiever Microsoft Certified Solution Developer (MCSD) for Microsoft .NET. He is also a member of ICCA, the Independent Computer Consultants Association.

Comments and Discussions

 
QuestionVery Useful Info Pin
Madhu Nair11-Feb-15 1:45
Madhu Nair11-Feb-15 1:45 
GeneralSystem.Web.Caching.Cache and WCF Pin
Khundalini25-Sep-09 6:09
Khundalini25-Sep-09 6:09 
QuestionIs the get property correct? Pin
toepoke8-Mar-09 1:41
toepoke8-Mar-09 1:41 
AnswerRe: Is the get property correct? Pin
forlixo11-Aug-10 3:17
forlixo11-Aug-10 3:17 
GeneralAttention... Pin
joaoxptoxpto21-Aug-08 23:04
joaoxptoxpto21-Aug-08 23:04 
GeneralRe: Attention... Pin
William F12-Dec-08 4:00
William F12-Dec-08 4:00 
AnswerRe: Attention... Pin
habakuk00729-Apr-11 3:18
habakuk00729-Apr-11 3:18 
Generalquestion Pin
ariell15-Oct-06 2:13
ariell15-Oct-06 2:13 
GeneralRe: question Pin
Kirby Turner15-Oct-06 2:58
Kirby Turner15-Oct-06 2:58 
GeneralRe: question Pin
ariell15-Oct-06 3:05
ariell15-Oct-06 3:05 
GeneralWhy instantiate HttpRuntime Pin
MeToo218-May-06 2:33
MeToo218-May-06 2:33 
GeneralJust wondering Pin
specialtreats27-Feb-06 13:48
specialtreats27-Feb-06 13:48 
Generalwww.whitepeaksoftware.com hard to read Pin
needmorebeach12-Apr-05 6:21
needmorebeach12-Apr-05 6:21 
GeneralRe: www.whitepeaksoftware.com hard to read Pin
Kirby Turner12-Apr-05 8:50
Kirby Turner12-Apr-05 8:50 
GeneralThis was timely ..... Pin
srdux18-Dec-04 19:43
srdux18-Dec-04 19:43 
GeneralWhat's the point Pin
chaldon14-Dec-04 23:12
chaldon14-Dec-04 23:12 
GeneralRe: What's the point Pin
Anonymous17-Jun-05 18:45
Anonymous17-Jun-05 18:45 
Generallock(typeof( [anyobject] )) is not recommended Pin
Eric Newton14-Dec-04 12:01
Eric Newton14-Dec-04 12:01 
GeneralVery Nice Idea Pin
Sameers Javed14-Dec-04 2:21
Sameers Javed14-Dec-04 2:21 
GeneralRe: Very Nice Idea Pin
Kirby Turner14-Dec-04 2:31
Kirby Turner14-Dec-04 2:31 
Thank you for the nice remarks. And I agree that while the work is simple it does show the robustness of the .NET Framework.

Best regards,

-KIRBY

White Peak Software Inc
www.whitepeaksoftware.com
GeneralRe: Very Nice Idea Pin
Anonymous16-Dec-04 16:07
Anonymous16-Dec-04 16:07 
AnswerRe: Very Nice Idea Pin
evoluzion1-May-08 17:33
evoluzion1-May-08 17:33 
GeneralRe: Very Nice Idea Pin
Hal Diggs3-Apr-09 7:52
professionalHal Diggs3-Apr-09 7:52 
GeneralUsing Cache only on server platforms Pin
Markus Rennings14-Dec-04 1:48
Markus Rennings14-Dec-04 1:48 
GeneralRe: Using Cache only on server platforms Pin
Kirby Turner14-Dec-04 2:02
Kirby Turner14-Dec-04 2:02 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.