本发明涉及计算机技术领域,具体地说是一种浏览器图表的服务端缓存方法。
背景技术:
图表泛指在屏幕中显示的,可直观展示统计信息属性(时间性、数量性等),对知识挖掘和信息直观生动感受起关键作用的图形结构,是一种很好的将对象属性数据直观、形象地“可视化”的手段。图表设计隶属于视觉传达设计范畴。
在现有技术的浏览器中,图表是必不可少的内容之一,用户经常需要查询该浏览器图表。查询图表的核心就是数据输出以及展现。如何能够及时响应用户请求,快速进行数据分析并将查询结果反馈给用户就成了提升用户体验的关键点。数据缓存是解决这个问题的最常见处理方式。
基于此,本发明提出了一种浏览器图表的服务端缓存方法。该方法采用数据缓存技术实现,数据缓存可以减少与数据库的交互次数,而且数据存储于内存当中,也会大大提升数据的提取和计算效率。
技术实现要素:
本发明的技术任务是针对以上不足之处,提供一种实用性强、有效解决上述问题的浏览器图表的服务端缓存方法。
一种浏览器图表的服务端缓存方法,其实现过程为:
首先在浏览器图表第一次加载时,在服务端对数据进行缓存;
当用户发起获取图表数据的请求时,直接从该服务端的缓存当中获取图表数据。
当用户在客户端发起获取图表数据的请求时,服务端首先从缓存当中获取数据,如果缓存中存在请求所需数据,那么直接将缓存数据返回给客户端;如果缓存当中没有所需数据,则将所需数据正常加载浏览器图标后再将其缓存到服务端。
当缓存当中没有所需数据时,分以下两步进行处理:
第一步、调用取数服务获取图表数据并返回给客户端;
第二步、通过将调用取数服务所获取的数据载入缓存当中。
服务端缓存的数据生命周期为20分钟。
当浏览图表结束后,将服务端的图表缓存进行回收,具体为:每当当前浏览器功能关闭或者退出系统时,系统对图表缓存进行回收处理,缓存失效并重新加载后,对图表已经载入的数据进行更新。
本发明的一种浏览器图表的服务端缓存方法和现有技术相比,具有以下有益效果:
本发明的一种浏览器图表的服务端缓存方法,通过将图表数据进行服务端缓存,避免了与数据库的多次交互,解决得了图表加载效率的问题;当第一次加载图表时,在服务端对请求的图表数据进行缓存,当用户在做翻页、导出以及打印操作时,系统不需要再次和数据库进行交互,直接从缓存当中获取图表数据,大幅度缩减了客户端请求的响应时间,大大提升了用户的操作体验,实用性强,适用范围广泛,易于推广。
附图说明
附图1为本发明的实现流程图。
具体实施方式
下面结合附图及具体实施例对本发明作进一步说明。
如附图1所示,一种浏览器图表的服务端缓存方法,包括以下几个步骤和内容:
(一) 图表初始化时,服务端对数据进行缓存。即在客户端第一次加载图表时,对图表数据进行缓存处理。
(二) 客户端发起获取图表数据的请求,每次调用取数引擎做取数操作前都要判断是否存在数据缓存,服务端首先从缓存当中获取数据,如果缓存中存在请求所需数据,那么直接将缓存数据返回给客户端;如果缓存当中没有所需数据,再调用取数服务获取数据,在将数据返回客户端的同时将数据放入缓存当中。
具体分以下两步进行处理:
第一步调用取数服务进行取数操作并完成数据分析,将处理后的数据反馈给客户端;
第二步通过异步操作(或者开启子线程)调用取数服务进行取数操作并将数据放入缓存当中。
(三)限定缓存的生命周期,并在关闭当前功能或者退出系统时对缓存进行回收。当缓存占用过多系统资源时自动回收缓存。
进一步的,缓存的生命周期为20分钟,与session的生命周期一致。每当当前功能关闭或者退出系统时,对图表缓存进行回收处理。当缓存占用过多系统资源时,根据优先级进行缓存回收。
(四) 缓存失效并重新加载后,对图表已经载入的数据进行更新,并对数据进行纠错处理。
(五) 针对实效性较高的图表,提供缓存设置的开发。
进一步的,本发明的具体代码如下:
/// <summary>
/// 缓存依赖项Key值
/// </summary>
public string Key { get; set; }
/// <summary>
/// 异步调用取数委托
/// </summary>
/// <returns></returns>
public delegate QueryResult AysnGetData();
/// <summary>
/// 异步调用取数的标志位字典对象
/// </summary>
private static readonly Dictionary<string, bool> AysnDictionary = new Dictionary<string, bool>();
/// <summary>
/// 获取图表数据
/// </summary>
/// <returns></returns>
public QueryResult GetPageData(GetBindingDataObject request)
{
Request = request;
IDataOperate operate = DataOperateFactory.CreateDataOperate(request);
bool flag = false; //缓存设置的开发标志位
RuntimeOptions runtimeOptions = ExportHelper.GetRuntimeOptions(Request.RuntimeOptionsID, Request.QueryID);
if (runtimeOptions != null && runtimeOptions.otherOptions != null)
{
//判断缓存设置的开关是否开启
if (runtimeOptions.otherOptions.dataCahce)
flag = true;
}
if (flag)
SetCacheDependent(); //设置缓存依赖
//从缓存中获取结果集
QueryResult result = HttpRuntime.Cache.Get(Id + Request.QueryID) as QueryResult;
if (flag)
{
if (result == null)
{
//异步调用取数过程中,结果集未缓存,直接调用取数接口取数
if (!AysnDictionary.ContainsKey(Id + Request.QueryID))
{
result = operate.GetData(AnalysisXmlParam(false));
//异步调用取数,并将结果集加入到缓存当中
BeginPageDataForCache();
}
else
{
if (!AysnDictionary[Id + Request.QueryID])
result = operate.GetData(AnalysisXmlParam(false));
}
}
else
{
result = OperateDataWithCache(result);
}
}
else
{
result = operate.GetData(AnalysisXmlParam(false));
}
return result;
}
/// <summary>
/// 设置缓存依赖项
/// </summary>
private void SetCacheDependent()
{
bool flag = true;
Key = Id + UserId;//缓存依赖项的key值
//判断缓存依赖项的key是否放生变动,如果有变动清楚缓存依赖项,并插入新的缓存依赖项
if (HttpRuntime.Cache.Count > 0)
{
foreach (System.Collections.DictionaryEntry item in HttpRuntime.Cache)
{
if (item.Key.ToString().Contains(UserId) && item.Key.ToString() != Key)
{
flag = false;
HttpRuntime.Cache.Remove(item.Key.ToString());
AysnDictionary.Clear();
HttpRuntime.Cache.Insert(Key, "cacheDependent");
break;
}
}
if (flag)
{
string cacheDependent = HttpRuntime.Cache.Get(Key) as string;
if (cacheDependent == null)
{
HttpRuntime.Cache.Insert(Key, "cacheDependent");
AysnDictionary.Clear();
}
}
}
else
{
HttpRuntime.Cache.Insert(Key, "cacheDependent");
}
}
/// <summary>
/// 异步调用取数
/// </summary>
private void BeginPageDataForCache()
{
if (AysnDictionary.ContainsKey(Id + Request.QueryID))
AysnDictionary[Id + Request.QueryID] = false;
else
AysnDictionary.Add(Id + Request.QueryID, false);
// ReSharper disable once RedundantDelegateCreation
AysnGetData aysnGetData = new AysnGetData(GetPageDataForCache);
aysnGetData.BeginInvoke(EndPageDataForCache, aysnGetData);
}
/// <summary>
/// 异步调用取数,异步调用结束将取数结果加入缓存当中
/// </summary>
/// <param name="result"></param>
private void EndPageDataForCache(IAsyncResult result)
{
AysnGetData aysnGetData = result.AsyncState as AysnGetData;
if (aysnGetData != null)
{
var queryResult = aysnGetData.EndInvoke(result);
var t = new TimeSpan(0, 0, 5, 0);
// ReSharper disable once RedundantExplicitArrayCreation
var dependency = new CacheDependency(null, new string[] { Key });
if (queryResult.Data.Tables.Count > 0 && queryResult.Data.Tables[0].Rows.Count > 0)
HttpRuntime.Cache.Insert(Id + Request.QueryID, queryResult, dependency, Cache.NoAbsoluteExpiration, t);
AysnDictionary.Clear();
}
}。
通过上面具体实施方式,所述技术领域的技术人员可容易的实现本发明。但是应当理解,本发明并不限于上述的具体实施方式。在公开的实施方式的基础上,所述技术领域的技术人员可任意组合不同的技术特征,从而实现不同的技术方案。
除说明书所述的技术特征外,均为本专业技术人员的已知技术。