BETA
Aby się zalogować, najpiew wybierz portal.
Aby się zarejestrować, najpiew wybierz portal.
Podaj słowa kluczowe
Słowa kluczowe muszą mieć co najmniej 3 sąsiadujące znaki alfanumeryczne
Pole zawiera niedozwolone znaki

Baza wiedzy











Cache w ASP.NET

10-01-2005 10:54 | User 131772
Artykuł pokazuje jak można przechowywać części strony, całe strony lub dane aplikacji www w pamięci podręcznej. Pokazuje techniki cache, które przyspieszają ładowanie się stron w przeglądarkach klientów i odciążają serwer www.

Co to jest caching ?

 

Caching w języku polskim oznacza przechowywanie danych w pamięci podręcznej, jest powszechnie stosowany w dzisiejszych systemach komputerowych i ma na celu zwiększenie wydajności działających aplikacji.

 

Kiedy stosujemy caching


- chcemy zmniejszyć obciążenie baz danych i serwera
- chcemy uzyskiwać szybszy dostęp do danych
- kiedy dane nie muszą być publikowane w czasie rzeczywistym lub są uaktualniane    nieregularnie (cache będzie odświeżany w momencie zmiany danych źródłowych)
- te same dane są prezentowane w różnych częściach witryny
 
ASP.NET oferuje trzy rodzaje przechowywania danych w pamięci podręcznej, które mogą być użyte przez aplikacje Web
 - Output caching – zapamiętanie wyników wykonania się strony
 - Fragment caching - zapisywanie w pamięci podręcznej fragmentów stron
 - Data caching – przechowywanie wybranych obiektów w pamięci


Zapamiętanie wyników wykonania strony (ang. Output caching) 


ASP.NET oferuje nam dwie możliwości przechowywania wartości stron w pamięci podręcznej.
- z wykorzystaniem dyrektywy OutputCache umieszonej na początku strony ASP.NET
- programistycznie z wykorzystaniem klasy HttpCachePolicy, do której mamy dostęp poprzez Page.Respons.Cache

 

Na początek prosty przykład, mający uzmysłowić nam idee przechowywania wykonania strony w pamięci operacyjnej.

 

Przykład 1

[Kod C#]

<%@ OutputCache Duration="60" VaryByParam="none" %>
<html>
  <script language="C#" runat="server">
    void Page_Load(Object sender, EventArgs e) {
        Czas.Text = DateTime.Now.ToString();
    }
  </script>
  <body>
    <h3><font face="Verdana">Przyklad uzycia OutputCache</font></h3>
    <p><i>Utworzono:</i> <asp:label id="Czas" runat="server"/></p>
  </body>
</html>

 

Po uruchomieniu strony otrzymujemy aktualną datę i godzinę jednak po odświeżeniu okna przeglądarki wynik pozostaje dalej taki sam. Dopiero po upływie pewnego czasu kolejne odświeżenie powoduje zmianę zawartości. Takie zachowanie się strony spowodowane jest wykonaniem się dyrektywy
<%@ OutputCache..., która umieszczona została  w kodzie strony ASP.NET .
Przyjrzyjmy się jej dokładniej.

 

[Kod C#]

<%@ OutputCache
Duration="#ofseconds"
Location="Any | Client | Downstream | Server | None"
Shared="True | False"
VaryByControl="controlname"
VaryByCustom="browser | customstring"
VaryByHeader="headers"
VaryByParam="parametername"
%>

 

Parametr Duration określa czas składowania strony i jest wyrażony w sekundach.
Location określa miejsce składowania informacji, jest parametrem domyślnym. Wartości jakie może przyjmować zostały przedstawione poniżej:

Any -  jest wartością domyślną,  oznacza że dane mogą być przechowywane na komputerze klienta z którego zostało wysłane zapytanie, na serwerze proxy, który pośredniczył w komunikacji lub bezpośrednio na serwerze który wygenerował stronę
Client - wyniki są przechowywane na komputerze klienta
Downstream - wartość będzie przechowywana „ poniżej ” serwera który wykonał zapytanie, w jednym z serwerów pośredniczących lub na komputerze klienta
None - cache jest wyłączony dla tej strony
ServerAndClient - wartość będzie przechowywana na serwerze wykonującym zapytanie lub na komputerze klienta
Server - wartość będzie przechowywana na serwerze wykonującym zapytanie

Parametr Shared  jest wartością logiczną i oznacza możliwość wykorzystywania tej samej wartość na różnych stronach, domyślnie przyjmuje wartość false.

VeryByHeaders umożliwia nam weryfikacje  ze względu na zawartość informacji w nagłówku HTTP np. :

 

[Kod C#]

<%@ OutputCache Duration="60" VaryByParam="none" VeryByHeaders="User-Agent" %>

 

W podanym przykładzie pierwsze wywołanie przez przeglądarkę danej strony powoduje jej dodanie do pamięci podręcznej, a  przy kolejnych wejściach strona będzie pobierane  z cachu. Kiedy jednak otworzymy stronę używając innej przeglądarki, zostanie ona ponownie wygenerowana i umieszczona w cachu.

Te same operacje możemy wykonywać stosując podejście programistyczne.

 

Parametr Duration możemy zastąpić poprzez wywołanie

[Kod C#]

Page.Response.Cache.SetExpires(DateTime.Now.AddSeconds(60))

 

Zastąpienie parametru VeryByParams:

[Kod C#]

Page.Response.Cache.VaryByParams["Imie"] = true;

 

Można też zdefiniować gdzie będą przechowywane dane:

Client Cache

[Kod C#]

Response.Cache.SetExpires(DateTime.Now.AddSeconds(60));
Response.Cache.SetCacheability(HttpCacheability.Private);


Proxy Server Cache

[Kod C#]

Response.Cache.SetExpires(DateTime.Now.AddSeconds(60));
Response.Cache.SetCacheability(HttpCacheability.Public);
Response.Cache.SetNoServerCaching();


Server Caching

[Kod C#]

Response.Cache.SetExpires(DateTime.Now.AddSeconds(60));
Response.Cache.SetCacheability(HttpCacheability.Server);

 

No Cache

[Kod C#]

użycie HttpCacheability.NoCache

 

Kolejny przykład pozwoli nam wyjaśnić działanie parametru VeryByParams .
Zmodyfikujmy Przykład 1 tak aby wyświetlał wartość  parametru imie.

 

Przykład 2

[Kod C#]

<%@ OutputCache Duration="60" VaryByParam="none" %>
<html>
 <script language="C#" runat="server">
       void Page_Load(Object sender, EventArgs e) {
        Czas.Text = DateTime.Now.ToString();
        Imie.Text = Request.Params["Imie"];
       }
 </script>
 <body>
    <h3><font face="Verdana">Przyklad uzycia OutputCache i parametru VaryByParams</font></h3>
    <p><i>Utworzono:</i>
    <asp:label id="Czas" runat="server" /></p>
    <p><b>Imie: </b><asp:label id="Imie" runat="server" /></p>
 </body>
</html>

 

Wykonajmy teraz kilka zapytań typu
 http://localhost/przyklad2.aspx?imie=Stefan ,  http://localhost/przyklad2.aspx?imie=Zenek

 

Wszystkie wyniki generowanych stron będą zgodne z działaniem Przykładu 1 .  Zmieńmy teraz wartość parametru VeryByParam na ”*”.  Otrzymywane wyniki będą teraz różne w zależności od wartości parametru Imie. Strona jest zapamiętywana dla każdej wartości.
Parametr ”*” oznacza ze strona ma być cachowana ze względu na wszystkie parametry. Można oczywiście sprecyzować ze względu, na które parametry, pisząc np. ”Imie” lub więcej np. ”Imie;Nazwisko”.

 

Przechowywanie fragmentów stron (ang. Fragment caching)


Załóżmy, że strona, którą chcemy stworzyć będzie miała menu, które bez względu na zmiany będzie pozostawało takie same. Niezmienne elementy zostaną zapamiętane na dysku co w znacznym stopniu odciąży serwer reszt zaś w mairę potrzeb będzie zmieniana.


Przykład 3

[Kod C#]

//Zdefiniujmy kontrolkę UserControl, która będzie symbolizować nasze Menu.
//W rzeczywistości będzie pokazywać date.
<%@ OutputCache Duration="60" VaryByParam="none" %>
<script language="C#" runat="server">
 void Page_Load(Object Src, EventArgs E ) {
  Wiadomosc.Text = DateTime.Now.ToString();  
 }
</script>
<div>
 <b>Ostatnia modyfikacja MENU: </b><asp:Label id="Wiadomosc" runat="server"/>
</div>

 
[Kod C#]

//Teraz utwórzmy stronę, na której będzie pokazywać się nasze Menu
<%@ Register TagPrefix="UserMenu" TagName="Menu" Src="menu.ascx" %>
<html>
 <script language="C#" runat="server">
    void Page_Load(Object sender, EventArgs e) {
        Czas.Text = DateTime.Now.ToString();    
    }
 </script>
 <body>
  <UserMenu:Menu runat="server" /><br/>
  <h3><font face="Verdana">Przyklad uzycia Fragment Caching</font></h3>
  <b>Czas: </b><asp:Label id="Czas" runat="server"/>  
 </body>
</html>
 

Po uruchomieniu zobaczymy, że nasze menu jest przechowywane w pamięci cache, a pozostała część strony jest na bieżąco modyfikowana.

 

Przechowywanie obiektów w pamięci (ang. Data caching).

 

Przyjrzyjmy się teraz bliżej klasie Cache, która w sposób programowy umożliwia dodawanie i zarządzanie obiektami w pamięci podręcznej.

Przyjrzyjmy się najpierw operacji dodawania obiektów.

Najprościej możemy to zrobić tak:

[Kod C#]

Cache[”MojObiekt”] = Wartosc;

 
Pobieramy w sposób analogiczny
[Kod C#]

Wartosc = Cache["MojObiekt"];
 if(Wartosc!=null)
  WyswietlDane(Wartosc);
 
Usuwamy korzystając z metody Cache.Remove
[Kod C#]

Cache.Remove(”MojObiekt”);

ASP.NET oferuje nam jednak bardziej zaawansowane metody umieszczania obiektów w pamięci podręcznej.

Add
 - zwraca referencje do dodanego obiektu
 - wykonanie nie powiedzie się, jeśli dodawany obiekt znajduje się już w Cache
Insert
- jest dużo bardziej rozbudowana niż metoda Add
- jeśli obiekt już istnienie to zostanie on nadpisany

 

W dalszej części będziemy omawiać metodę Insert.

[Kod C#]

public void Insert(
   string key,
   object value,
   CacheDependency dependencies,
   DateTime absoluteExpiration,
   TimeSpan slidingExpiration,
   CacheItemPriority priority,
   CacheItemRemovedCallback onRemoveCallback
);

 
key - nazwa obiektu, który ma zostać zapisany w pamięci podręcznej
value - wartość obiektu, który ma zostać zapisany w pamięci podręcznej
dependencies - plik, katalog lub inny obiekt w pamięci podręcznej, od którego zależą dane dodawanego   obiektu. Jeśli te zostaną zmienione obiekt zostaje usunięty
absoluteExpiration - bezwzględna data, po której upływa ważność obiektu
slidingExpiration - czas, po którym  dane są usuwane z cache
priority - parametr określa ważność obiektu w pamięci cache. Ma to zastosowanie w szczególnych przypadkach (np. w przypadku braku pamięci). Im koszt uzyskania takiego obiektu jest wyższy tym wyższy należy nadać mu priorytet. Wartość ta ma znaczenie jeśli dane są usuwane automatycznie.
onRemoveCallback - wywoływana w momencie usuwania obiektu z pamięci podręcznej

 

Przykładowo możemy wykonać następujące operacje


Wygaśniecie danych po upływie 1 minuty

[Kod C#]

Cache.Insert("MojaDana",oString,null, DateTime.Now.AddMinutes(1),NoSlidingExpiration);


 
Wygaśnięcie danych  po upływie 1 minuty od ostatniego wywołania

[Kod C#]

Cache.Insert("MojaDana",oString,null,NoAbsoluteExpiration,TimeSpan.FromSeconds(60));

 
Dane wygasną w momencie zmiany zawartości pliku file.xml

[Kod C#]

Cache.Insert("MojaDana", oString, new CacheDependency(Server.MapPath(\\file.xml)));

 
Przeanalizujmy teraz na przykładzie parametr dependencies .

 

Przykład 4
Załóżmy, że chcemy wyświetlać dane zapisane w pliku xml. Dane te należy wczytać, przetworzyć i wyświetlić. Oczywiście operacje te wymagają dużego nakładu pracy ze strony serwera. Dlatego umieszczamy wynik w cache i używamy go aż do momentu kiedy plik źródłowy nie zostanie zmodyfikowany.

[Kod C#]

<%@ Import Namespace="System.IO" %>
<html>
 <script language="C#" runat="server">
 void Page_Load(Object Src, EventArgs E ) {
    LoadData();
 }
 void LoadData(){
  String Dane = (String)Cache["MojeDane"];
  if(Dane==null){
  String file ="file.txt"; //dla uproszczenia bedziemy wczytywac plik txt
               FileStream fs = new FileStream(file,FileMode.Open,FileAccess.Read);
  StreamReader reader = new StreamReader(fs);
  Dane = reader.ReadLine();
 
               Cache.Insert("MojeDane",Dane,new CacheDependency(file));
 
               TextInfo.Text = "Dane zostały wczytane";
  fs.Close();     
  }
  else TextInfo.Text = "Dane sa juz wczytane";
   InfoPlik.Text = Dane;
 }
 </script>
 <body>
  <p>Dane: <asp:Label id="TextInfo" runat="server"/></p>
  <p>Informacja: <asp:Label id="InfoPlik" runat="server"/></p>
 </body>
</html>

 
W celu uproszczenia przykładu naszym plikiem jest zwykły plik tekstowy. W funkcji LoadData() sprawdzamy czy nasz obiekt znajduje się w cachu. Jeśli nie to odczytujemy jedną linijkę z pliku, wyświetlamy ją i umieszczamy w pamięci.
Teraz ruchamiamy przeglądarke. Odświeżamy okno przeglądarki, wyświetlana zawartość pliku pozostaje taka sama ale zasygnalizowane zostaje, że dane zostały pobrane  z cachu. Zmieńmy teraz zawartość file.txt i odświeżmy. Zostanie wyświetlona nowa informacja zawarta w pliku i potwierdzenie o wczytaniu nowych danych.
Taki efekt uzyskujemy wykorzystując obiekt klasy CacheDependies, który został „podpięty” do naszego pliku i w momencie jego modyfikacji powoduje usunięcie danych z cache.
W tym momencie należy wspomnieć, w jaki sposób dane są usuwane. W powyższym przykładzie dane są całkowicie usuwane z cache, możliwe jest jednak wywołanie, w momencie usuwania, zdefiniowanej przez nas funkcji jako parametr onRemoveCallback.
Taki sposób postępowania jest potrzebny, gdy dane wygasną a my chcemy, aby natychmiast, bez ingerencji przeglądarki klienta nowe dane były generowane i umieszczone w pamięci.

 

Przykład 5
Zmodyfikujemy poprzedni przykład, tak aby pokazać obsługę usuwanych elementów z Cachu.

[Kod C#]

<%@ Import Namespace="System.IO" %>
<html>
 <script language="C#" runat="server">
 
 void Page_Load(Object Src, EventArgs E ) {
    LoadData();
 }
 void LoadData(){
  String Dane = (String)Cache["MojeDane"];
 
 if(Dane==null){
  String file =”file.txt
  FileStream fs = new FileStream(file,FileMode.Open,FileAccess.Read);
  StreamReader reader = new StreamReader(fs);
  Dane = reader.ReadLine();
 
  CacheItemRemovedCallback onRemove = new CacheItemRemovedCallback(this. onRemoveCallBack);
 
  Cache.Insert("MojeDane", Dane, new CacheDependency(file),DateTime.Now.AddMinutes(1),TimeSpan.Zero, CacheItemPriority.High, onRemove);
  TextInfo.Text = "Dane zostały wczytane";
  fs.Close();     
 }
 else
  TextInfo.Text = "Dane sa juz wczytane";
 InfoPlik.Text = Dane;
 }
 void onRemoveCallBack(string str, object obj, CacheItemRemovedReason r){
  String Dane = "Nazwa w cachu: "+str+" Wartosc objektu: "+ obj + " Powód usuniecia: "+r.ToString();
  Cache.Insert("MojeDane", Dane);
 }
 </script>
 <body>
  <p>Dane: <asp:Label id="TextInfo" runat="server"/></p>
  <p>Informacja: <asp:Label id="InfoPlik" runat="server"/></p>
 </body>
</html>

 
 
Dane w momencie zmiany zawartości pliku file.txt zostają usunięte z cachu, wywoływana zostaje metoda onRemoveCallBack, w której wykonuje operacje na pamięci podręcznej. Funkcja ta przekazuje kolejno parametry: nazwę pod jaką była nasza dana przechowywana w cachu, jej wartość oraz powód dla którego została usunięta.  W naszym przypadku powodem była zmiana zawartości pliku file.txt czyli parametr CacheItemRemovalReason przyjął wartość DependencyChanged.
Obiekt ten przyjmuje również inne wartości typu enum:
Expired — upłynął okres ważności elementu pamięci podręcznej;
Removed — element został usunięty z pamięci podręcznej w wyniku wywołania metody Cache.Remove;
Underused — system usunął element z pamięci podręcznej gdyż na komputerze zaczynało brakować pamięci.
 
Odnośniki
http://www.asp.net/Tutorials/quickstart.aspx
 
http://www.microsoft.com/seminar/events/series/msdnaspnetoct.mspx

 

Podobne artykuły

Komentarze 1

ryo87
ryo87
0 pkt.
Nowicjusz
16-10-2011
oceń pozytywnie 0
Przydatny artykul, dzieki!
pkt.

Zaloguj się lub Zarejestruj się aby wykonać tę czynność.