No ASP.NET 1.x, podemos usar CacheDependency para implementar estratégias de dependência de cache, mas como essa classe é selada, não podemos herdá-la para implementar nossas próprias estratégias. Mas com o ASP.NET 2.0, já podemos derivar nossas próprias classes de dependência de cache dessa classe.
Suponha que queiramos criar uma página e precisemos obter as informações das postagens mais recentes na página inicial do blog. Para melhorar o desempenho, esperamos que os dados da página só sejam regenerados quando a página inicial do blog park for atualizada, caso contrário serão obtidos diretamente do cache. Como conseguir?
1. Projete a classe BlogCacheDependency
e analise-a primeiro. Em primeiro lugar, não há dúvida de que esta classe deve ser derivada de CacheDependency, e então pode ser usada no método Insert do Cache, ou usada na classe AggregateDependency.
Em segundo lugar, da perspectiva do RSS fornecido pelo Blog Park e do design da página, você pode colocar dados RSS no cache e usar uma conversão de estilo ao exibi-los. Ao verificar as dependências, precisamos apenas comparar se o RSS atual é igual ao RSS do site.
Uma questão mais importante é: quando verificamos e comparamos os dados RSS? Em cada pedido? Obviamente que não. Isso é quase o mesmo que não usar cache e, na verdade, adiciona uma carga desnecessária. Que tal fazer check-in sem solicitação? Podemos usar um Timer para controlá-lo e deixá-lo verificar se há uma atualização regularmente. Se houver uma atualização, ele notificará a dependência da mudança.
Sabemos que a classe CacheDependency possui uma propriedade HasChanged, mas como o BlogCacheDependency informa sua classe base quando detecta uma alteração de dependência? Esta é a missão do novo método NotifyDependencyChanged na classe CacheDependency no ASP.NET 2.0.
Além disso, para facilitar a reutilização, a classe BlogCacheDependency deve possuir um feed de dados para salvar a URL dos dados RSS que queremos obter. Há também um intervalo de tempo para facilitar o ajuste da velocidade de atualização durante o uso.
OK, vamos dar uma olhada no código de implementação real:
1public class BlogCacheDependency: CacheDependency
2{
3 temporizador privado _tickTimer;
4 privado int _timeInterval;
5 XPathNavigator privado _rss;
6 string privada _feed;
7
8 XPathNavigator RSS público
9 {
10 obter
11 {
12 retorno _rss;
13}
14}
15
16 BlogCacheDependency público (string feed, int timeInterval)
17 {
18 _feed = feed;
19 _timeInterval = timeInterval;
20 _rss = GetRSS();
21 _tickTimer = novo temporizador(novo TimerCallback(CheckDependencyCallback),
22 isto, _timeInterval * 1000, _timeInterval * 1000);
vinte e três }
vinte e quatro
25 XPathNavigator GetRSS() privado
26 {
27 XPathDocument rssDoc = novo XPathDocument(_feed);
28 return rssDoc.CreateNavigator();
29}
30
31 public void CheckDependencyCallback (remetente do objeto)
32 {
33 BlogCacheDependency bcd = remetente como BlogCacheDependency;
34 XPathNavigator newRSS = GetRSS();
35 se (newRSS.OuterXml! = _rss.OuterXml)
36 {
37 bcd.NotifyDependencyChanged(bcd, EventArgs.Empty);
38}
39}
40
41 substituição protegida void DependencyDispose()
42 {
43 _tickTimer = nulo;
44 base.DependencyDispose();
45}
46}
47
48
Aqui, o construtor de BlogCacheDependency usa _tickTimer para implementar um mecanismo de verificação regular de atualizações, que chama o método CheckDependencyCallback de acordo com o intervalo de tempo definido.
O método CheckDependencyCallback compara as duas informações RSS. Se forem diferentes, o método NotifyDependencyChanged é chamado para notificar a classe base de que a dependência do cache correspondente foi alterada e os dados no cache devem ser limpos.
2. Design da página
A seguir está o código da página (resumido), que mostra como usar o BlogCacheDependency:
1<script runat="server">
2 Page_Load nulo protegido (remetente do objeto, EventArgs e)
3 {
Feed de 4 strings = " http://www.cnblogs.com/RSS.aspx ";
5 if (Cache[feed] == nulo)
6 {
7 BlogCacheDependency bcd = novo BlogCacheDependency(feed, 600);
8 Cache.Insert(feed, bcd.RSS, bcd);
9 Label1.Text = "Os dados atuais acabaram de ser obtidos e atualizados no cache!";
10}
11 mais
12 {
13 Label1.Text = "Os dados atuais são obtidos do cache!";
14}
15 RssXml.XPathNavigator = Cache[feed] como System.Xml.XPath.XPathNavigator;
16 RssXml.TransformSource = "traduzir.xsl";
17}
18</script>
19
20<corpo>
21 <form id="form1" runat="servidor">
22 postagens mais recentes do Blog Park:
23<br />
24 <asp:Xml ID="RssXml" runat="servidor" />
25<br />
26 <asp:Label ID="Label1" runat="server" ForeColor="red" />
27 </form>
28</corpo>
29
Neste exemplo, o intervalo de tempo definido para acesso à lista de últimas postagens da página inicial do blog park é de 600 segundos, ou seja, o status da atualização é verificado a cada 10 minutos.
Vários pontos dignos de nota:
1. Preste atenção ao atributo RssXml.XPathNavigator usado. Algumas pessoas podem se perguntar por que RssXml.Document não é usado. Na verdade, o atributo Document foi abolido no .NET 2.0. A substituição recomendada é o atributo XPathNavigator. Como você pode ver na classe BlogCacheDependency anterior, ele é criado a partir de XPathDocument.CreateNavigator(). A classe XPathDocument fornece um cache rápido somente leitura, que é obviamente mais adequado para este exemplo.
2. Pense bem, qual é a finalidade do método DependencyDispose na classe BlogCacheDependency? Como isso difere do método Dispose? Vamos pensar sobre isso. Se uma alteração de dependência for encontrada durante a verificação de atualizações, mas a solicitação não for enviada novamente, o método CheckDependencyCallback será executado continuamente em intervalos? Se este for realmente o caso, não seria completamente redundante, porque desde que uma alteração seja detectada uma vez, não há necessidade de verificar novamente. E se rastrearmos ou registrarmos logs, podemos descobrir que, de fato, desde que sejam encontradas alterações de dependência, elas não serão verificadas novamente. Qual é o segredo? Se você pensar bem, saberá que o método NotifyDependencyChanged tem muito mistério, e a razão pela qual existe um método DependencyDispose está aqui. Vale a pena saborear as ideias de design nele contidas.
3. Não vou falar mais sobre o translate.xsl usado na página
, mas aqui estão os principais códigos:
1<xsl:template match="channel">
2 <div>
3 <xsl:for-each select="item">
4 <a>
5 <xsl:attribute name="href">
6 <xsl:valor-de select="link"/>
7 </xsl:attribute>
8 <xsl:valor-de select="título"/>
9</a>
10<br />
11 </xsl:for-each>
12</div>
13</xsl:template>
4. Execução:
Esta é uma captura de tela da execução inicial:
Quando nenhuma postagem nova aparece na página inicial do blog garden, atualizamos a página e sempre obtemos a seguinte página:
Assim que houver uma nova postagem, a imagem anterior aparecerá ao atualizar.
5. Você quer estar mais avançado?
Se você é tão preguiçoso quanto eu ou mais preguiçoso que eu, considere usar javascript para escrever uma pequena função que atualiza automaticamente a página e, em seguida, decora a página ou empacota-a em um componente reutilizável para uso em seu site. deseja apenas criar algo como uma “coleção de conteúdo que mais me interessa” nesta máquina? Bem, acho que o efeito será muito bom.