Udostępnij za pośrednictwem


Buforowanie danych przy uruchamianiu aplikacji (VB)

Autor : Scott Mitchell

Pobierz plik PDF

W dowolnej aplikacji internetowej niektóre dane będą często używane, a niektóre dane będą rzadko używane. Możemy zwiększyć wydajność naszej aplikacji ASP.NET, ładując z wyprzedzeniem często używane dane, czyli technikę znaną jako. W tym samouczku przedstawiono jedno podejście do aktywnego ładowania, które polega na ładowaniu danych do pamięci podręcznej podczas uruchamiania aplikacji.

Wprowadzenie

W dwóch poprzednich samouczkach przedstawiono buforowanie danych w warstwach prezentacji i buforowania. W buforowaniu danych za pomocą obiektu ObjectDataSource przyjrzeliśmy się używaniu funkcji buforowania obiektuDataSource do buforowania danych w warstwie prezentacji. Buforowanie danych w architekturze zbadało buforowanie w nowej, oddzielnej warstwie buforowania. Oba te samouczki używały reaktywnego ładowania podczas pracy z pamięcią podręczną danych. Podczas reaktywnego ładowania za każdym razem, gdy są wymagane dane, system najpierw sprawdza, czy znajduje się w pamięci podręcznej. W przeciwnym razie pobiera dane ze źródła źródłowego, takiego jak baza danych, a następnie zapisuje je w pamięci podręcznej. Główną zaletą reaktywnego ładowania jest łatwość implementacji. Jedną z jego wad jest nierówna wydajność w żądaniach. Wyobraź sobie stronę, która używa warstwy buforowania z poprzedniego samouczka do wyświetlania informacji o produkcie. Gdy ta strona jest odwiedzana po raz pierwszy lub odwiedzana po raz pierwszy po eksmitowanym buforowanym danych z powodu ograniczeń pamięci lub osiągnięto określony czas wygaśnięcia, dane muszą zostać pobrane z bazy danych. W związku z tym żądania tych użytkowników będą trwać dłużej niż żądania użytkowników, które mogą być obsługiwane przez pamięć podręczną.

Proaktywne ładowanie zapewnia alternatywną strategię zarządzania pamięcią podręczną, która zapewnia wydajność między żądaniami przez załadowanie buforowanych danych przed ich potrzebami. Zazwyczaj aktywne ładowanie korzysta z pewnego procesu, który okresowo sprawdza lub jest powiadamiany o aktualizacji danych bazowych. Następnie ten proces aktualizuje pamięć podręczną, aby zachować jej świeżość. Proaktywne ładowanie jest szczególnie przydatne, jeśli dane bazowe pochodzą z powolnego połączenia z bazą danych, usługi sieci Web lub innego szczególnie powolnego źródła danych. Jednak takie podejście do aktywnego ładowania jest trudniejsze do zaimplementowania, ponieważ wymaga tworzenia, zarządzania i wdrażania procesu sprawdzania zmian i aktualizowania pamięci podręcznej.

Inną odmianą aktywnego ładowania i typem, który będziemy eksplorować w tym samouczku, jest ładowanie danych do pamięci podręcznej podczas uruchamiania aplikacji. Takie podejście jest szczególnie przydatne w przypadku buforowania danych statycznych, takich jak rekordy w tabelach odnośników bazy danych.

Uwaga

Aby uzyskać bardziej szczegółowe informacje na temat różnic między aktywnym i reaktywnym ładowaniem, a także listami zalet, wad i zaleceń dotyczących implementacji, zapoznaj się z sekcją Zarządzanie zawartością pamięci podręcznejprzewodnika po architekturze buforowania dla aplikacji .NET Framework.

Krok 1. Określanie danych do buforowania podczas uruchamiania aplikacji

Przykłady buforowania przy użyciu reaktywnego ładowania, które sprawdziliśmy w poprzednich dwóch samouczkach, działają dobrze z danymi, które mogą okresowo ulec zmianie i nie są zbyt długie do wygenerowania. Jeśli jednak buforowane dane nigdy się nie zmieniają, wygaśnięcie używane przez ładowanie reaktywne jest zbędne. Podobnie, jeśli buforowane dane trwają znacznie długo, to ci użytkownicy, których żądania znajdą pustą pamięć podręczną, będą musieli długo czekać podczas pobierania danych bazowych. Rozważ buforowanie danych statycznych i danych, które generowanie przy uruchamianiu aplikacji zajmuje wyjątkowo dużo czasu.

Chociaż bazy danych mają wiele dynamicznych, często zmieniających się wartości, większość ma również dość dużo danych statycznych. Na przykład praktycznie wszystkie modele danych mają jedną lub więcej kolumn, które zawierają określoną wartość z stałego zestawu opcji. Patients Tabela bazy danych może zawierać kolumnęPrimaryLanguage, której zestaw wartości może być angielski, hiszpański, francuski, rosyjski, japoński itd. Często te typy kolumn są implementowane przy użyciu tabel odnośników. Zamiast przechowywać ciąg w języku angielskim lub francuskim w Patients tabeli, tworzona jest druga tabela zawierająca często dwie kolumny — unikatowy identyfikator i opis ciągu — z rekordem dla każdej możliwej wartości. Kolumna PrimaryLanguage w Patients tabeli przechowuje odpowiedni unikatowy identyfikator w tabeli odnośników. Na rysunku 1 pacjent John Doe jest językiem podstawowym jest angielski, podczas gdy Ed Johnson jest rosyjski.

Tabela Languages jest tabelą odnośników używaną przez tabelę Pacjentów

Rysunek 1.Languages Tabela jest tabelą odnośników używaną przez tabelę Patients

Interfejs użytkownika do edycji lub tworzenia nowego pacjenta zawiera listę rozwijaną dozwolonych języków wypełnionych rekordami w Languages tabeli. Bez buforowania za każdym razem, gdy ten interfejs jest odwiedzany, system musi wykonywać zapytania względem Languages tabeli. Jest to marne i niepotrzebne, ponieważ wartości tabeli odnośników zmieniają się bardzo rzadko, jeśli kiedykolwiek.

Dane można buforować Languages przy użyciu tych samych technik reaktywnego ładowania, które przeanalizowano w poprzednich samouczkach. Ładowanie reaktywne używa jednak czasu wygaśnięcia, który nie jest wymagany w przypadku statycznych danych tabeli odnośników. Buforowanie przy użyciu ładowania reaktywnego byłoby lepsze niż wcale, ale najlepszym rozwiązaniem byłoby proaktywne ładowanie danych tabeli odnośników do pamięci podręcznej podczas uruchamiania aplikacji.

W tym samouczku dowiesz się, jak buforować dane tabeli odnośników i inne informacje statyczne.

Krok 2. Badanie różnych sposobów buforowania danych

Informacje mogą być buforowane programowo w aplikacji ASP.NET przy użyciu różnych metod. W poprzednich samouczkach pokazano już, jak używać pamięci podręcznej danych. Alternatywnie obiekty mogą być programowo buforowane przy użyciu statycznych elementów członkowskich lub stanu aplikacji.

Podczas pracy z klasą zazwyczaj należy utworzyć wystąpienie klasy przed uzyskaniem dostępu do jej składowych. Aby na przykład wywołać metodę z jednej z klas w warstwie logiki biznesowej, musimy najpierw utworzyć wystąpienie klasy:

Dim productsAPI As New ProductsBLL()
productsAPI.SomeMethod()
productsAPI.SomeProperty = "Hello, World!"

Zanim będziemy mogli wywołać metodę SomeMethod lub pracować z elementem SomeProperty, musimy najpierw utworzyć wystąpienie klasy przy użyciu słowa kluczowego New . Właściwości SomeMethod i SomeProperty są skojarzone z określonym wystąpieniem. Okres istnienia tych elementów członkowskich jest powiązany z okresem istnienia skojarzonego obiektu. Z drugiej strony statyczne składowe to zmienne, właściwości i metody, które są współużytkowane przez wszystkie wystąpienia klasy, a w związku z tym mają okres istnienia tak długo, jak klasa. Statyczne elementy członkowskie są oznaczane przez słowo kluczowe Shared.

Oprócz statycznych elementów członkowskich dane mogą być buforowane przy użyciu stanu aplikacji. Każda aplikacja ASP.NET przechowuje kolekcję nazw/wartości współużytkowanych przez wszystkich użytkowników i strony aplikacji. Do tej kolekcji można uzyskać dostęp przy użyciu HttpContext właściwości klasyApplicationi używać jej z klasy ASP.NET s code-behind w następujący sposób:

Application("key") = value
Dim value As Object = Application("key")

Pamięć podręczna danych udostępnia znacznie bogatszy interfejs API do buforowania danych, zapewniając mechanizmy wygasania na podstawie czasu i zależności, priorytety elementów pamięci podręcznej itd. W przypadku statycznych elementów członkowskich i stanu aplikacji takie funkcje muszą zostać dodane ręcznie przez dewelopera strony. Jednak w przypadku buforowania danych podczas uruchamiania aplikacji przez cały okres istnienia aplikacji zalety pamięci podręcznej danych to elementy łamią. W tym samouczku przyjrzymy się kodowi, który używa wszystkich trzech technik buforowania danych statycznych.

Krok 3. BuforowanieSuppliersdanych tabeli

Tabele bazy danych Northwind, które zaimplementowaliśmy do tej pory, nie zawierają żadnych tradycyjnych tabel odnośników. Cztery tabele DataTable zaimplementowane w naszej tabeli modelu DAL, których wartości nie są statyczne. Zamiast poświęcać czas, aby dodać nową tabelę DataTable do dal, a następnie nową klasę i metody do biblioteki BLL, na potrzeby tego samouczka po prostu udajmy, że Suppliers dane tabeli są statyczne. W związku z tym możemy buforować te dane podczas uruchamiania aplikacji.

Aby rozpocząć, utwórz nową klasę o nazwie StaticCache.cs w folderze CL .

Tworzenie klasy StaticCache.vb w folderze CL

Rysunek 2. Tworzenie StaticCache.vb klasy w folderze CL

Musimy dodać metodę, która ładuje dane podczas uruchamiania do odpowiedniego magazynu pamięci podręcznej, a także metody zwracające dane z tej pamięci podręcznej.

<System.ComponentModel.DataObject()> _
Public Class StaticCache
    Private Shared suppliers As Northwind.SuppliersDataTable = Nothing
    Public Shared Sub LoadStaticCache()
        ' Get suppliers - cache using a static member variable
        Dim suppliersBLL As New SuppliersBLL()
        suppliers = suppliersBLL.GetSuppliers()
    End Sub
    
    <DataObjectMethodAttribute(DataObjectMethodType.Select, True)> _
    Public Shared Function GetSuppliers() As Northwind.SuppliersDataTable
        Return suppliers
    End Function
End Class

Powyższy kod używa statycznej zmiennej składowej , suppliersdo przechowywania wyników z SuppliersBLL metody klasy s GetSuppliers() , która jest wywoływana LoadStaticCache() z metody . Metoda LoadStaticCache() ma być wywoływana podczas uruchamiania aplikacji. Po załadowaniu tych danych podczas uruchamiania aplikacji każda strona, która musi współpracować z danymi dostawcy, może wywołać metodę StaticCache klasy s GetSuppliers() . W związku z tym wywołanie bazy danych w celu pobrania dostawców odbywa się tylko raz, podczas uruchamiania aplikacji.

Zamiast używać statycznej zmiennej składowej jako magazynu pamięci podręcznej, moglibyśmy też użyć stanu aplikacji lub pamięci podręcznej danych. Poniższy kod przedstawia klasę ponownie w celu użycia stanu aplikacji:

<System.ComponentModel.DataObject()> _
Public Class StaticCache
    Public Shared Sub LoadStaticCache()
        ' Get suppliers - cache using application state
        Dim suppliersBLL As New SuppliersBLL()
        HttpContext.Current.Application("key") = suppliers
    End Sub
    
    <DataObjectMethodAttribute(DataObjectMethodType.Select, True)> _
    Public Shared Function GetSuppliers() As Northwind.SuppliersDataTable
        Return TryCast(HttpContext.Current.Application("key"), _
            Northwind.SuppliersDataTable)
    End Function
End Class

W LoadStaticCache()systemie informacje o dostawcy są przechowywane w kluczu zmiennej aplikacji. Jest zwracany jako odpowiedni typ (Northwind.SuppliersDataTable) z GetSuppliers(). Podczas gdy dostęp do stanu aplikacji można uzyskać w klasach kodu ASP.NET stron przy użyciu metody Application("key"), w architekturze musimy użyć HttpContext.Current.Application("key") polecenia , aby uzyskać bieżący HttpContextelement .

Podobnie pamięć podręczna danych może być używana jako magazyn pamięci podręcznej, jak pokazano w poniższym kodzie:

<System.ComponentModel.DataObject()> _
Public Class StaticCache
    Public Shared Sub LoadStaticCache()
        ' Get suppliers - cache using a static member variable
        Dim suppliersBLL As New SuppliersBLL()
        HttpRuntime.Cache.Insert("key", suppliers, Nothing, _
            Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, _
            CacheItemPriority.NotRemovable, Nothing)
    End Sub
    <System.ComponentModel.DataObjectMethodAttribute_
    (System.ComponentModel.DataObjectMethodType.Select, True)> _
    Public Shared Function GetSuppliers() As Northwind.SuppliersDataTable
        Return TryCast(HttpRuntime.Cache("key"), Northwind.SuppliersDataTable)
    End Function
End Class

Aby dodać element do pamięci podręcznej danych bez wygaśnięcia na podstawie czasu, użyj System.Web.Caching.Cache.NoAbsoluteExpiration wartości i System.Web.Caching.Cache.NoSlidingExpiration jako parametrów wejściowych. Wybrano to konkretne przeciążenie metody pamięci podręcznej Insert danych, aby umożliwić określenie priorytetu elementu pamięci podręcznej. Priorytet jest używany do określania, które elementy mają być pomłodliwe z pamięci podręcznej, gdy dostępna pamięć jest niska. W tym miejscu używamy priorytetu NotRemovable, który gwarantuje, że ten element pamięci podręcznej nie zostanie przeszycony.

Uwaga

W tym samouczku pobierana jest implementacja StaticCache klasy przy użyciu metody statycznej zmiennej składowej. Kod technik stanu aplikacji i pamięci podręcznej danych jest dostępny w komentarzach w pliku klasy.

Krok 4. Wykonywanie kodu podczas uruchamiania aplikacji

Aby wykonać kod po pierwszym uruchomieniu aplikacji internetowej, musimy utworzyć specjalny plik o nazwie Global.asax. Ten plik może zawierać programy obsługi zdarzeń dla zdarzeń aplikacji, sesji i na poziomie żądania. W tym miejscu można dodać kod, który będzie wykonywany za każdym razem, gdy aplikacja zostanie uruchomiona.

Global.asax Dodaj plik do katalogu głównego aplikacji internetowej, klikając prawym przyciskiem myszy nazwę projektu witryny internetowej w Eksplorator rozwiązań programu Visual Studio i wybierając polecenie Dodaj nowy element. W oknie dialogowym Dodawanie nowego elementu wybierz typ elementu Globalny klasa aplikacji, a następnie kliknij przycisk Dodaj.

Uwaga

Jeśli masz już Global.asax plik w projekcie, typ elementu Globalnej klasy aplikacji nie będzie wyświetlany w oknie dialogowym Dodawanie nowego elementu.

Dodawanie pliku Global.asax do katalogu głównego aplikacji internetowej

Rysunek 3. Dodawanie Global.asax pliku do katalogu głównego aplikacji internetowej (kliknij, aby wyświetlić obraz pełnowymiarowy)

Global.asax Domyślny szablon pliku zawiera pięć metod w tagu po stronie <script> serwera:

  • Application_Start uruchamia się po pierwszym uruchomieniu aplikacji internetowej
  • Application_End działa, gdy aplikacja jest zamykana
  • Application_Error jest wykonywany za każdym razem, gdy nieobsługiwany wyjątek osiągnie aplikację
  • Session_Start wykonuje po utworzeniu nowej sesji
  • Session_End uruchamia się, gdy sesja wygasła lub porzucona

Program Application_Start obsługi zdarzeń jest wywoływany tylko raz podczas cyklu życia aplikacji. Aplikacja uruchamia się po raz pierwszy zasób ASP.NET jest żądany z aplikacji i nadal działa do momentu ponownego uruchomienia aplikacji, co może się zdarzyć przez zmodyfikowanie zawartości /Bin folderu, zmodyfikowanie , zmodyfikowanie Global.asaxzawartości w App_Code folderze lub zmodyfikowanie Web.config pliku, między innymi. Zapoznaj się z tematem ASP.NET Przegląd cyklu życia aplikacji , aby zapoznać się z bardziej szczegółowym omówieniem cyklu życia aplikacji.

W przypadku tych samouczków musimy tylko dodać kod do Application_Start metody, więc możesz usunąć inne. W Application_Startpliku po prostu wywołaj metodę StaticCache s LoadStaticCache() klasy, która załaduje i buforuje informacje o dostawcy:

<%@ Application Language="VB" %>
<script runat="server">
    Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
        StaticCache.LoadStaticCache()
    End Sub
</script>

To wszystko jest do tego! Podczas uruchamiania LoadStaticCache() aplikacji metoda pobierze informacje o dostawcy z biblioteki BLL i zapisze je w statycznej zmiennej składowej (lub dowolnego magazynu pamięci podręcznej, którego używasz w StaticCache klasie). Aby zweryfikować to zachowanie, ustaw punkt przerwania w metodzie Application_Start i uruchom aplikację. Należy pamiętać, że punkt przerwania jest trafiony po uruchomieniu aplikacji. Kolejne żądania nie powodują Application_Start jednak wykonania metody.

Użyj punktu przerwania, aby sprawdzić, czy program obsługi zdarzeń Application_Start jest wykonywany

Rysunek 4. Użyj punktu przerwania, aby sprawdzić, Application_Start czy program obsługi zdarzeń jest wykonywany (kliknij, aby wyświetlić obraz pełnowymiarowy)

Uwaga

Jeśli nie trafisz do Application_Start punktu przerwania podczas pierwszego rozpoczęcia debugowania, jest to spowodowane tym, że aplikacja została już uruchomiona. Wymuś ponowne uruchomienie aplikacji, modyfikując pliki Global.asax lub Web.config , a następnie spróbuj ponownie. Możesz po prostu dodać (lub usunąć) pusty wiersz na końcu jednego z tych plików, aby szybko ponownie uruchomić aplikację.

Krok 5. Wyświetlanie buforowanych danych

W tym momencie StaticCache klasa ma wersję danych dostawcy buforowanych podczas uruchamiania aplikacji, do których można uzyskać dostęp za pośrednictwem metody GetSuppliers() . Aby pracować z danymi z warstwy prezentacji, możemy użyć obiektu ObjectDataSource lub programowo wywołać StaticCache metodę klasy s GetSuppliers() z klasy ASP.NET strony kodu za klasą. Przyjrzyjmy się używaniu kontrolek ObjectDataSource i GridView do wyświetlania buforowanych informacji o dostawcy.

Zacznij od otwarcia AtApplicationStartup.aspx strony w folderze Caching . Przeciągnij element GridView z przybornika do projektanta, ustawiając jego ID właściwość na Suppliers. Następnie z tagu inteligentnego GridView wybierz opcję utworzenia nowego obiektu ObjectDataSource o nazwie SuppliersCachedDataSource. Skonfiguruj obiekt ObjectDataSource do użycia StaticCache metody s GetSuppliers() klasy.

Konfigurowanie obiektu ObjectDataSource do używania klasy StaticCache

Rysunek 5. Konfigurowanie obiektu ObjectDataSource do używania StaticCache klasy (kliknij, aby wyświetlić obraz pełnowymiarowy)

Użyj metody GetSuppliers(), aby pobrać buforowane dane dostawcy

Rysunek 6. Używanie GetSuppliers() metody do pobierania buforowanych danych dostawcy (kliknij, aby wyświetlić obraz pełnowymiarowy)

Po ukończeniu pracy kreatora program Visual Studio automatycznie doda pola BoundFields dla każdego pola danych w programie SuppliersDataTable. Znaczniki deklaratywne gridView i ObjectDataSource powinny wyglądać podobnie do następujących:

<asp:GridView ID="Suppliers" runat="server" AutoGenerateColumns="False" 
    DataKeyNames="SupplierID" DataSourceID="SuppliersCachedDataSource" 
    EnableViewState="False">
    <Columns>
        <asp:BoundField DataField="SupplierID" HeaderText="SupplierID" 
            InsertVisible="False" ReadOnly="True" 
            SortExpression="SupplierID" />
        <asp:BoundField DataField="CompanyName" HeaderText="CompanyName" 
            SortExpression="CompanyName" />
        <asp:BoundField DataField="Address" HeaderText="Address" 
            SortExpression="Address" />
        <asp:BoundField DataField="City" HeaderText="City" 
            SortExpression="City" />
        <asp:BoundField DataField="Country" HeaderText="Country" 
            SortExpression="Country" />
        <asp:BoundField DataField="Phone" HeaderText="Phone" 
            SortExpression="Phone" />
    </Columns>
</asp:GridView>
<asp:ObjectDataSource ID="SuppliersCachedDataSource" runat="server" 
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetSuppliers" TypeName="StaticCache" />

Rysunek 7 przedstawia stronę po wyświetleniu za pośrednictwem przeglądarki. Dane wyjściowe są takie same, jak w przypadku ściągania danych z klasy BLL SuppliersBLL , ale użycie StaticCache klasy zwraca dane dostawcy w pamięci podręcznej podczas uruchamiania aplikacji. Punkty przerwania można ustawić w metodzie StaticCache klasy , GetSuppliers() aby zweryfikować to zachowanie.

Dane buforowanego dostawcy są wyświetlane w siatceView

Rysunek 7. Dane buforowanego dostawcy są wyświetlane w widoku GridView (kliknij, aby wyświetlić obraz pełnowymiarowy)

Podsumowanie

Większość każdego modelu danych zawiera sporo danych statycznych, zwykle implementowanych w formie tabel odnośników. Ponieważ te informacje są statyczne, nie ma powodu, aby stale uzyskiwać dostęp do bazy danych za każdym razem, gdy te informacje muszą być wyświetlane. Ponadto ze względu na jego statyczny charakter podczas buforowania danych nie ma potrzeby wygaśnięcia. W tym samouczku pokazano, jak pobrać takie dane i buforować je w pamięci podręcznej danych, stanie aplikacji i za pomocą zmiennej statycznej składowej. Te informacje są buforowane podczas uruchamiania aplikacji i pozostają w pamięci podręcznej przez cały okres istnienia aplikacji.

W tym samouczku i w ciągu ostatnich dwóch przyjrzeliśmy się buforowaniu danych przez okres istnienia aplikacji, a także przy użyciu wygasań opartych na czasie. Jednak w przypadku buforowania danych bazy danych wygaśnięcie oparte na czasie może być mniejsze niż idealne. Zamiast okresowo opróżniać pamięć podręczną, najlepszym rozwiązaniem byłoby wykluczenie buforowanego elementu tylko wtedy, gdy bazowe dane bazy danych zostaną zmodyfikowane. Jest to idealne rozwiązanie, korzystając z zależności pamięci podręcznej SQL, które przeanalizujemy w następnym samouczku.

Szczęśliwe programowanie!

Informacje o autorze

Scott Mitchell, autor siedmiu książek ASP/ASP.NET i założyciel 4GuysFromRolla.com, współpracuje z technologiami internetowymi firmy Microsoft od 1998 roku. Scott pracuje jako niezależny konsultant, trener i pisarz. Jego najnowsza książka to Sams Teach Yourself ASP.NET 2.0 w ciągu 24 godzin. Można do niego dotrzeć pod adresem mitchell@4GuysFromRolla.com. Lub za pośrednictwem swojego bloga, który można znaleźć na stronie http://ScottOnWriting.NET.

Specjalne podziękowania

Ta seria samouczków została sprawdzona przez wielu pomocnych recenzentów. Recenzenci w tym samouczku byli Teresa Murphy i Zack Jones. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, upuść mi wiersz pod adresem mitchell@4GuysFromRolla.com.