HttpContext的Items集合是ASP.NET保守得最好的秘密之一。它是IDictionary键/值对的对象集合,在HttpRequest的生存期中共享。它只存在于HttpRequest中。状态为什么要存储这么短的时间?有如下原因:
在IHttpModule和IHttpHandler之间共享内容。如果编写一个定制的IHttpModule,就可以存储用户的信息,供以后在页面中使用。
在一个页面上的两个UserControl实例之间通信。假定编写一个用于横幅广告的UserControl。该控件的两个实例可以从HttpContext.Items中选择广告,防止在同一个页面上显示重复的内容。
存储成本很高的调用的结果,防止该调用在页面上出现多次。如果有多个UserControl,每个UserControl都从很昂贵的大型数据库中提取并显示一组数据,这些UserControl就可以从HttpContext.Items中提取需要的数据。数据库只使用一次。
一个HttpRequest中的各个单元需要处理相同或类似的数据。如果数据的生存期只是一个请求,就可以考虑使用HttpContext. Items作为短期的高速缓存。
Items集合存储对象,这与本章前面使用的许多集合相同。在检索时,需要把这些对象转换回特定的类型。
在支持Web的数据库访问层中,请求的预先高速缓存使用下面的编码模式很容易实现。注意,这个示例代码是一个设计模式,其中不包含MyData类,它仅用于演示:
VB Public Shared Function GetExpensiveData(ID As Integer) As MyData Dim key as string = "data" & ID.ToString() Dim d as MyData = _ CType(HttpContext.Current.Items(key), MyData) If d Is Nothing Then d = New Data() 'Go to the Database, do whatever... HttpContext.Current.Items(key) = d End If Return d End Function
C# public static MyData GetExpensiveData(int ID) { string key = "data" + ID.ToString(); MyData d = (MyData) HttpContext.Current.Items[key]; if (d == null) { d = new Data(); //Go to the Database, do whatever... HttpContext.Current.Items[key] = d; } return d; }
这段代码检查当前HttpContext的Items集合,看看它是否已有数据。如果没有,就从相应的支持数据库中提取,然后存储在Items集合中。在同一个HttpRequest中对这个函数的后续调用都会得到已高速缓存的对象。
与所有的优化和缓存一样,不成熟的优化是所有罪恶的祸根。应仔细考虑对高速缓存的需求和改进情况。不要仅凭感觉就进行高速缓存,而应在确实需要时进行高速缓存。