Source: http://www.cnblogs.com/keepsilence/archive/2009/07/23/1529199.html
Because of the large access volume, the database cannot be directly operated when page views are made. If files are used for recording, although the database pressure is slowed down, the server I/O is a test, and the cache is exactly. net, so I want to use httphandler with cache to reduce I/O operations, so that I/O and database pressure are solved!
First, create a statistics class library.
1. CreateCounterhelperStatistics
Using system;
Using system. Web;
Using system. Web. caching;
Using system. Collections. Specialized;
Using system. Data;
Using system. Data. sqlclient;
Using system. configuration;
Using system. text;
Using system. IO;
Namespace MySpace. Counter
{
/// <Summary>
/// Summary of counter.
/// </Summary>
Public class counterhelper
{
Private int _ hits = 0; // The total number of clicks
Private string _ filename = "";
Private string filepth = string. empty;
Private string errorlogfilepth = string. empty;
Private int [] hitsarr = {-, 0}; // hitsarr [0] indicates the total number of hits. hitsarr indicates the number of hits of the previous day. hitsarr indicates the number of hits of the current day.
Cacheitemremovedcallback onremove = NULL; // cacheitemremovedcallback object
Private string cachename = "updatehitsforexpired"; // cache name
Private object lockforaddhits = new object (); // lockforaddhits lock
Private object lockforitemremovedfromcachehits = new object (); // itemremovedfromcachehits lock
/** //
// constructor
///
Public counterhelper (string filename)
{< br> _ filename = filename;
cachename = filename;
httpcontext CTX = httpcontext. current;
filepth = CTX. server. mappath ("~ /"+ _ Filename +". txt ");
errorlogfilepth = CTX. server. mappath ("~ /"+ _ Filename +". txt ");
loadhits ();
}
/** // <Summary>
/// Save the cumulative number of clicks to the global variable. When it reaches a certain number, save it to the text file and clear it.
/// </Summary>
Public void addhits ()
{
Lock (lockforaddhits)
{
If (hits! = 0)
{
Add ();
If (hits> 200)
{
// -- Remove
Httpruntime. cache. Remove (cachename );
}
}
Else
{
Onremove = new cacheitemremovedcallback (itemremovedfromcache );
Httpruntime. cache. insert (
Cachename,
"This object for expired ",
Null,
Datetime. Now. addseconds (5 ),
Timespan. Zero,
System. Web. caching. cacheitempriority. Normal,
Onremove
);
Add ();
}
}
}
/** // <Summary>
/// Save to a text file
/// </Summary>
/// <Param name = "allid"> </param>
Private void savehitstofile (INT hits)
{
String hitsinfo = string. empty;
Datetime lastwritetime = file. getlastwritetime (filepth );
If (datetime. Today-lastwritetime). totaldays> 0)
{
// -- Indicates the first time data is written today.
Hitsarr [1] = hitsarr [2]; // -- assign the total number of clicks to the previous day
Hitsarr [2] = hits; // -- set the number of clicks today
Using (streamwriter = new streamwriter (filepth, false ))
{
Streamwriter. Write (string. Format ("{0}, {1}, {2}", hitsarr [0] + hits, hitsarr [1], hits ));
Streamwriter. Flush ();
}
}
Else
{
Using (streamwriter = new streamwriter (filepth, false ))
{
Streamwriter. write (string. format ("{0}, {1}, {2}", hitsarr [0] + hits, hitsarr [1], hitsarr [2] + hits ));
Streamwriter. Flush ();
}
}
}
/** // <Summary>
/// The callback event triggered when the cache is removed or expired
/// </Summary>
/// <Param name = "key"> </param>
/// <Param name = "value"> </param>
/// <Param name = "reason"> </param>
Private void itemremovedfromcache (string key, object value, cacheitemremovedreason reason)
{
Try
{
// Clear and write to a text file
# Region
Int hits = 0 ;;
Lock (lockforitemremovedfromcachehits)
{
Hits = hits;
Hitsarr [0] + = hits;
Hitsarr [2] + = hits;
Hits = 0;
}
If (hits = 0)
{
Return;
}
Else
{
Savehitstofile (hits );
}
# Endregion
}
Catch (exception ex)
{
Using (streamwriter = new streamwriter (errorlogfilepth, false ))
{
Streamwriter. Write (string. Format ("Time: {0}/R/n Description: {1}/R/N", datetime. Now, Ex. Message ));
Streamwriter. Flush ();
}
}
}
/** //
// obtain all clicks
///
Public int allhits
{< br> Get
{< br> return hitsarr [0] + hits;
}< BR >}
/** //
// obtain the number of hits of the previous day
///
Public int yesterdayhits
{
Get
{< br> return hitsarr [1];
}< BR >}
/** // <Summary>
/// Obtain the number of clicks today
/// </Summary>
Public int todayhits
{
Get
{
Return hitsarr [2] + hits;
}
}
/** // <Summary>
/// Load the number of clicks
/// </Summary>
Private void loadhits ()
{
If (httpruntime. cache [cachename] = NULL)
{
Httpcontext CTX = httpcontext. Current;
If (! File. exists (filepth ))
{
// -- Used for the first time
Using (streamwriter = new streamwriter (filepth ))
{
Streamwriter. Write (string. Format ("{0}, {1}, {2}", 0, 0, 0 ));
Streamwriter. Flush ();
}
Hitsarr [0] = 0;
Hitsarr [1] = 0;
Hitsarr [2] = 0;
}
Else
{
String hitsinfo = string. empty;
Using (streamreader objstreamreader = new streamreader (filepth ))
{
Hitsinfo = objstreamreader. Readline ();
}
If (hitsinfo! = "")
{
String [] arr = hitsinfo. Split (',');
Hitsarr [0] = convert. toint32 (ARR [0]); // All
Hitsarr [1] = convert. toint32 (ARR [1]); // Yesterday
Hitsarr [2] = convert. toint32 (ARR [2]); // Today
}
Else
{
Hitsarr [0] = 0;
Hitsarr [1] = 0;
Hitsarr [2] = 0;
}
}
Httpruntime. cache ["B" + cachename] = hitsarr;
}
Else
{
Hitsarr = (INT []) httpruntime. cache ["B" + cachename];
// Hitsarr [0] + = 1;
// Hitsarr [2] + = 1;
}
}
/** // <Summary>
/// Obtain the total number of clicks
/// </Summary>
Private int hits
{
Get
{
Return _ hits;
}
Set
{
_ Hits = value;
}
}
/** // <Summary>
/// Accumulate
/// </Summary>
/// <Param name = "ID"> </param>
Private void add ()
{
If (hitsarr [2] <14000)
{
// _ Hits = _ hits + new random (datetime. Now. Second). Next (60, 80 );
_ Hits = _ hits + 1;
}
Else
{
_ Hits = _ hits + 1; // _ hits = _ hits + new random (datetime. Now. Second). Next (); returns a random number in the specified range.
}
}
/** // <Summary>
/// File name
/// </Summary>
/// <Summary>
/// Get the file name
/// </Summary>
Public String filename
{
Get {return _ filename ;}
Set {_ filename = value ;}
}
}
}
2. Create httphandler
<% @ Webhandler Language = "C #" class = "httphandler" %>
Using system;
Using system. Web;
Using system. Text. regularexpressions;
namespace MySpace. Counter
{< br> ///
/// abstract description of hitshandler.
//
public class counterhandler: ihttphandler
{< br> Public void processrequest (httpcontext CTX)
{< br> counterhelper objcounterhelper = new counterhelper (CTX. request. querystring ["ID"]. tostring ();
objcounterhelper. addhits ();
CTX. response. write (string. format ("document. write ('page access: {0} yesterday: {1} today: {2} ID: {3} ') ", objcounterhelper. allhits, objcounterhelper. yesterdayhits, objcounterhelper. todayhits, CTX. request. URL. absoluteuri);
}
Public bool isreusable
{
Get
{Return false ;}
}
}
}
Create a website after the DLL is generated, and then reference the DLL!
Add the configuration in Web. config:
<Httphandlers>
<Add verb = "*" Path = "count. aspx" type = "MySpace. Counter. counterhandler, MySpace. Counter"/>
</Httphandlers>
Finally, the call is OK on the web page. PageCodeAs follows:
<! Doctype HTML public "-// W3C // dtd xhtml 1.0 transitional // en" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<HTML xmlns = "http://www.w3.org/1999/xhtml">
<Head runat = "server">
<Title> No title page </title>
<Script language = "JavaScript" src = 'count. aspx? Id = O4 '> </SCRIPT>
</Head>
<Body>
<Form ID = "form1" runat = "server">
<Div>
</Div>
</Form>
</Body>
</Html>
Here we will only introduce writing files. If you want to write data into the database, read the values in the file directly!