|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
BackgroundCache is one of the most important aspects of building high performance and scalable web applications. As one of the key features in ASP.NET AJAX, calling a script method from a client would be used a lot when building AJAX applications using ASP.NET. The following is a sample to show how to enable server-side caching. <asp:ScriptManager ID="ScriptManager1" runat="server" ScriptMode="Debug">
<Services>
<asp:ServiceReference Path="CacheService.asmx" />
</Services>
</asp:ScriptManager>
<script language="javascript" type="text/javascript">
var count = 0;
function getServerTime()
{
window.count ++;
CacheService.GetServerTime(onSucceeded);
}
function onSucceeded(result)
{
Sys.Debug.trace(result.format("HH:mm:ss"));
if (count < 6)
{
window.setTimeout(getServerTime, 3000);
}
elses
{
window.count = 0;
}
}
</script>
<input type="button" value="GetCurrentTime" onclick="getServerTime()" />
<br /><br />
<textarea cols="20" rows="10" id="TraceConsole"></textarea>
There's a [ScriptService]
public class CacheService : System.Web.Services.WebService
{
[WebMethod]
public DateTime GetServerTime()
{
return DateTime.Now;
}
}
Open the page and click the button, and we'll see the following result on the page:
Cache on server-sideScript method access in ASP.NET AJAX has a built-in cache mechanism on the server-side but it seems that only a few developers realize that. They always cache the data in the [WebMethod(CacheDuration=10)]
public DateTime GetServerTime()
{
return DateTime.Now;
}
Like when building web services in ASP.NET, we use the same way to let ASP.NET cache the request for the same resource with the same content, by setting the private static void InitializeCachePolicy(WebServiceMethodData methodData,
HttpContext context)
{
int cacheDuration = methodData.CacheDuration;
if (cacheDuration > 0)
{
context.Response.Cache.SetCacheability(HttpCacheability.Server);
context.Response.Cache.SetExpires(DateTime.Now.AddSeconds(
(double) cacheDuration));
context.Response.Cache.SetSlidingExpiration(false);
context.Response.Cache.SetValidUntilExpires(true);
if (methodData.ParameterDatas.Count > 0)
{
context.Response.Cache.VaryByParams["*"] = true;
}
else
{
context.Response.Cache.VaryByParams.IgnoreParams = true;
}
}
else
{
context.Response.Cache.SetNoServerCaching();
context.Response.Cache.SetMaxAge(TimeSpan.Zero);
}
}
If ASP.NET AJAX found that the Let's see the effect of caching.
Comparing with caching data programmatically, the most important advantage of setting the public string GetResult(int key, bool ignoreRest, string args1, string args2) { ... }
In the scenario above, almost all programmers would cache the data only for the different values of the Cache on client-sideI used the HttpWatch basic edition to capture the communication between the client and the server. Here's the snapshot.
Each time we access the script method, the same content would be posted to the server, receiving the same result. Although the result would be cached, we only save the execution time of the method, and the round trips would be taken each time we invoke the method. It means that if the the size of the result is huge or the bandwidth is low, the accesses to script methods are still time-consuming jobs for the users. So it would be better if we can cache the result on the client-side so that the user can get the result immediately if we call the same method with the same parameters again - even if the network connection is lost. Here we go. At first, we can only use the HTTP GET method to access the script method if we want to let the browser cache the result for us. [WebMethod]
[ScriptMethod(UseHttpGet = true)]
public DateTime GetServerTime() { ... }
We'll use the traditional way to cache the result on the client-side. [WebMethod]
[ScriptMethod(UseHttpGet = true)]
public DateTime GetServerTime()
{
HttpCachePolicy cache = HttpContext.Current.Response.Cache;
cache.SetCacheability(HttpCacheability.Private);
cache.SetExpires(DateTime.Now.AddSeconds((double)10));
cache.SetMaxAge(new TimeSpan(0, 0, 10));
return DateTime.Now;
}
We set the Cache-Control public, max-age=0
Date Fri, 29 Jun 2007 00:44:14 GMT
Expires Fri, 29 Jun 2007 00:44:24 GMT
The problem is the value of public void SetMaxAge(TimeSpan delta)
{
if (delta < TimeSpan.Zero)
{
throw new ArgumentOutOfRangeException("delta");
}
if (s_oneYear < delta)
{
delta = s_oneYear;
}
if (!this._isMaxAgeSet || (delta < this._maxAge))
{
this.Dirtied();
this._maxAge = delta;
this._isMaxAgeSet = true;
}
}
After calling the [WebMethod]
[ScriptMethod(UseHttpGet = true)]
public DateTime GetServerTime()
{
HttpCachePolicy cache = HttpContext.Current.Response.Cache;
cache.SetCacheability(HttpCacheability.Private);
cache.SetExpires(DateTime.Now.AddSeconds((double)10));
FieldInfo maxAgeField = cache.GetType().GetField(
"_maxAge", BindingFlags.Instance | BindingFlags.NonPublic);
maxAgeField.SetValue(cache, new TimeSpan(0, 0, 10));
return DateTime.Now;
}
Let's check the effect.
Seems no different from the previous one, but HttpWatch could tell us this:
Nothing is sent and received, so the cached responses have really been "cached" and the round trips between the client and the server have been saved! Please note that the cache is also "parameter combination specific", which means if you use different parameters, you'll get the new result since the request URL (query string) has been changed. The cache on the client-side is successful due to the response header the browser received. Please focus on the Cache-Control public, max-age=10
Date Fri, 29 Jun 2007 00:54:32 GMT
Expires Fri, 29 Jun 2007 00:54:42 GMT
The most important advantage of caching responses on client-side is that it improves the performance significantly. But it has disadvantages. Perhaps, the most serious one of them is the usage of reflection. Reflection operations are always restricted in some kind of host circumstance. If you want to use reflection, you should follow one of three ways. But actually, there's few chance to apply any one of them in a virtual web hosting.
Another disadvantage of caching responses on the client-side is that different clients would execute the server method at least once to get the result before caching. In this aspect, server side caching works better since the server method would be executed only once (for the same parameter combinations) and the cached result could be sent to the requests from all clients. But we could minimize the execution time of the method, e.g., cache the result programmatically on the server-side as we always do. ConclusionWe have talked about three ways of caching to improvement the performance of script methods access in ASP.NET AJAX, in this article. It's time to draw a conclusion.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||