对于WEB地理信息系统来说,一个需要特别强调的是系统的响应速度,有许多方法来提高系统的速度,我们今天要提到的是利用缓存来提高系统的速度。
例如在执行查询时,如果前后多次所查询的得到结果都相同,我们可以将第一次查询的结果放到内存中缓存中去,第二或第二次调用时,我们可以直接返回缓存的信息,节省了从地图服务器中查询的时间,从而提高了响应的效率。
ASP.NET提供了强大的、便于使用的缓存机制,用于将需要大量服务器资源来创建的对象存储在内存中。缓存这些类型的资源会大大改进应用程序的性能。缓存是由Cache类实现的,缓存程序是每个应用程序专用的。缓存生存期依赖于应用程序的生存期,重新启动应用程序后,将重新创建Cache对象。
设计Cache类是为了便于使用。可以将项放置在Cache中,并在以后使用简单的键/值对来检索这些项。Cache类提供了强大的功能,允许自定义如何缓存项以及将他们缓存多长时间。例如,当缺乏系统内存时,缓存会自动移除很少使用的或优先级较低的项以释放内存。该技术也成为清理,这是缓存确保过期数据不使用宝贵的服务器资源的方式之一。当执行清理时,可以只是Cache给予某些项比其他项更高的优先级。若要指示项的重要性,可以在使用Add或Insert方法添加项时,指定一个CacheItemPritory枚举值。当使用Add或Insert方法将项添加到缓存时,您还可以建立项的过期策略。可以通过使用DateTime值指定项的确切过期时间(绝对过期时间),来定义项的生存期。也可以使用TimeSpan值指定一个弹性过期时间,弹性过期时间允许根据项的上次访问时间来指定该项过期之前的运行时间。一旦项过期,便将它从缓存中移除。试图检索它的值的行为将返回null,除非该项被重新添加到缓存中。
此为,ASP.NET允许根据外部文件、目录(文件依赖项)或另一个缓存项(键依赖项)来定义缓存项的有效性。如果具有关联依赖项的项发生更改,缓存项便会失效并从缓存中移除。可以使用该技术在项的数据源更改时从缓存中移除这些项。
以下例子代码如何在查询时利用ASP.NET提供的缓存机制。
首先在GetCallbackResult 方法的最前面加入如下代码,判断是否存在某一缓存,如果存在(第二次调用相同的操作),则直接将缓存结果返回,如果不存在(首次调用),则不影响程序的执行:
// 判断是否有相应的缓存信息
string cachedResponse = Cache[callbackArg] as string;
if (cachedResponse != null)
{
return cachedResponse;
}
然后在GetCallbackResult方法返回response字符串之前,加入如下代码,用于将查询结果保存到缓存中:
TimeSpan cacheDuration = new TimeSpan(0, 0, 999999);
Cache.Add(callbackArg, response, null,
DateTime.Now.Add(cacheDuration),
System.Web.Caching.Cache.NoSlidingExpiration,
System.Web.Caching.CacheItemPriority.NotRemovable, null);
上述代码通过Cache的Add方法将查询结果缓存起来。该方法的第一个参数是用于引用该项的缓存键;第二个参数是要添加到缓存的项;第三个参数表示文件依赖项或缓存键依赖项,当任何依赖项更改时,该对象即无效,并从缓存中移除。如果没有依赖项,则此参数为空引用;第四个参数是所添加对象将过期并从缓存中移除的时间。如果使用可调过期,则该参数必须为NoAbsoluteExpiration;第五个参数表示最后一次访问所添加对象时与该对象过期时之间的时间间隔。如果该值等效于20分钟,则该对象在最后一次被访问20分钟之后将过期并从缓存中移除。若果使用绝对过期,则该参数必须为NoSlidingExpiration;第六个参数是对象的相对的优先级,由CacheItemPriority枚举表示。缓存在退出对象时使用该值;具有较低优先级的对象在具有较高优先级的对象之前被从缓存移除;最后一个参数表示从缓存中移除对象时所调用的委托(如果提供)。当从缓存中删除应用程序的对象时,可使用它来通知应用程序。
GetCallbackResult方法的完整代码如下:
string ICallbackEventHandler.GetCallbackResult()
{
// 判断是否有相应的缓存信息
string cachedResponse = Cache[callbackArg] as string;
if (cachedResponse != null)
{
return cachedResponse;
}
// 将传入参数依据&分割符分到querystring变量中
Array keyValuePairs = callbackArg.Split("&".ToCharArray());
NameValueCollection queryString = new NameValueCollection();
string[] keyValue;
string response = "";
if (keyValuePairs.Length > 0)
{
for (int i = 0; i < keyValuePairs.Length; i++)
{
keyValue = keyValuePairs.GetValue(i).ToString().Split("=".ToCharArray());
queryString.Add(keyValue[0], keyValue[1]);
}
}
else
{
keyValue = callbackArg.Split("=".ToCharArray());
if (keyValue.Length > 0)
queryString.Add(keyValue[0], keyValue[1]);
}
// 是否进行缓存,对于属性查询图形不进行缓存
bool needCached = true;
// 针对参数中指定的ActiveType不同执行不同操作
string controlType = queryString["ActiveType"];
string eventArg = queryString["EventArg"];
switch (controlType)
{
case "GetResourceContent":
response = GisFunctionality.GetResourceContent(Map1);
break;
case "ShowFieldInfo":
response = GisFunctionality.ShowFieldInfo(Map1, eventArg);
break;
case "AttributeQuery":
response = GisFunctionality.AttributeQuery(Map1, eventArg, queryString["Condtion"]);
needCached = false;
break;
default:
break;
}
if (needCached)
{
TimeSpan cacheDuration = new TimeSpan(0, 0, 999999);
Cache.Add(callbackArg, response, null,
DateTime.Now.Add(cacheDuration),
System.Web.Caching.Cache.NoSlidingExpiration,
System.Web.Caching.CacheItemPriority.NotRemovable, null);
}
return response;
}
编译并运行程序。可以通过设置断点来确定缓存机制是否起到了作用。