逐步解說:在 WPF 應用程式中快取應用程式資料

快取可讓您將資料儲存在記憶體中,以進行快速存取。 重新存取資料時,應用程式可以從快取中取得資料,而不是從原始來源進行擷取。 這可以改善效能和延展性。 此外,暫時無法使用資料來源時,快取可讓資料可用。

.NET Framework 提供類別,可讓您在 .NET Framework 應用程式中使用快取。 這些類別位於 命名空間中 System.Runtime.Caching

注意

命名空間 System.Runtime.Caching 是 .NET Framework 4 中的新功能。 此命名空間可讓所有 .NET Framework 應用程式使用快取。 在舊版的 .NET Framework 中,快取只能在 命名空間中使用 System.Web ,因此需要 ASP.NET 類別的相依性。

本逐步解說說明如何使用 .NET Framework 中提供的快取功能,做為 Windows Presentation Foundation (WPF) 應用程式的一部分。 在逐步解說中,您會快取文字檔的內容。

本逐步解說所述的工作包括下列各項:

  • 建立 WPF 應用程式專案。

  • 將參考新增至 .NET Framework 4。

  • 初始化快取。

  • 加入包含文字檔內容的快取專案。

  • 提供快取專案的收回原則。

  • 監視快取檔案的路徑,並通知快取實例對受監視專案所做的變更。

必要條件

為了完成這個逐步解說,您需要:

  • Visual Studio 2010。

  • 包含少量文字的文字檔。 (您會在訊息方塊中顯示文字檔的內容。逐步解說中說明的程式碼假設您使用下列檔案:

    c:\cache\cacheText.txt

    不過,您可以使用任何文字檔,並在此逐步解說中對程式碼進行小變更。

建立 WPF 應用程式專案

您將從建立 WPF 應用程式專案開始。

建立 WPF 應用程式

  1. 啟動 Visual Studio。

  2. 在 [檔案] 功能表中,按一下 [ 新增 ],然後按一下 [ 新增專案 ]。

    [新增專案] 對話方塊隨即出現。

  3. 在 [已安裝的範本] 底下 ,選取您想要使用的程式設計語言 ( Visual Basic Visual C# )。

  4. 在 [ 新增專案 ] 對話方塊中,選取 [WPF 應用程式 ]。

    注意

    如果您沒有看到 WPF 應用程式 範本,請確定您是以支援 WPF 的 .NET Framework 版本為目標。 在 [ 新增專案 ] 對話方塊中,從清單中選取 [.NET Framework 4]。

  5. 在 [ 名稱] 文字方塊中,輸入專案的名稱。 例如,您可以輸入 WPFCaching

  6. 選取 [為解決方案建立目錄] 核取方塊。

  7. 按一下 [確定]

    WPF 設計工具會在 [設計 ] 檢視中 開啟,並顯示 MainWindow.xaml 檔案。 Visual Studio 會 建立 My Project 資料夾、Application.xaml 檔案和 MainWindow.xaml 檔案。

以 .NET Framework 為目標,並新增快取元件的參考

根據預設,WPF 應用程式會以 .NET Framework 4 用戶端設定檔為目標。 若要在 WPF 應用程式中使用 System.Runtime.Caching 命名空間,應用程式必須以 .NET Framework 4 為目標(而非 .NET Framework 4 用戶端設定檔),而且必須包含命名空間的參考。

因此,下一個步驟是變更 .NET Framework 目標,並新增命名空間的 System.Runtime.Caching 參考。

注意

在 Visual Basic 專案和 Visual C# 專案中,變更 .NET Framework 目標的程式不同。

在 Visual Basic 中變更目標 .NET Framework

  1. [方案總管] 中 ,以滑鼠右鍵按一下專案名稱,然後按一下 [ 屬性 ]。

    應用程式的屬性視窗隨即顯示。

  2. 按一下 [編譯] 索引標籤。

  3. 在視窗底部,按一下 [進階編譯選項... ]。

    [ 進階編譯器設定 ] 對話方塊隨即顯示。

  4. 在 [ 目標架構][所有組態] 清單中,選取 [.NET Framework 4]。 (請勿選取 .NET Framework 4 用戶端設定檔。)

  5. 按一下 [確定]

    [目標 Framework 變更] 對話方塊隨即出現。

  6. 在 [ 目標架構變更 ] 對話方塊中,按一下 [ ]。

    專案已關閉,然後重新開啟。

  7. 依照下列步驟新增快取元件的參考:

    1. 方案總管 中,以滑鼠右鍵按一下專案的名稱,然後按一下 [ 新增參考 ]。

    2. 選取 [.NET] 索引 標籤,選取 System.Runtime.Caching ,然後按一下 [ 確定 ]。

變更 Visual C# 專案中的目標 .NET Framework

  1. 方案總管 中,以滑鼠右鍵按一下專案名稱,然後按一下 [ 屬性 ]。

    應用程式的屬性視窗隨即顯示。

  2. 按一下 [應用程式] 索引標籤。

  3. 在 [ 目標架構] 清單中,選取 [.NET Framework 4]。 (請勿選取 .NET Framework 4 用戶端設定檔 。)

  4. 依照下列步驟新增快取元件的參考:

    1. 以滑鼠右鍵按一下 [ 參考] 資料夾,然後按一下 [ 新增參考 ]。

    2. 選取 [.NET] 索引 標籤,選取 System.Runtime.Caching ,然後按一下 [ 確定 ]。

將按鈕新增至 WPF 視窗

接下來,您將新增按鈕控制項,並建立按鈕 Click 事件的事件處理常式。 稍後您會將程式碼新增至 ,因此當您按一下按鈕時,會快取並顯示文字檔的內容。

若要新增按鈕控制項

  1. 方案總管 中,按兩下 MainWindow.xaml 檔案加以開啟。

  2. 從 [工具箱 ] 的 [通用 WPF 控制項 ] 底下 ,將控制項拖曳 ButtonMainWindow 視窗。

  3. 在 [ 屬性] 視窗中,將 控制項的 Button 屬性設定 Content [取得快取 ]。

初始化快取和快取專案

接下來,您將新增程式碼以執行下列工作:

  • 建立快取類別的實例,也就是您將具現化新的 MemoryCache 物件。

  • 指定快取使用 HostFileChangeMonitor 物件來監視文字檔中的變更。

  • 讀取文字檔,並將其內容快取為快取專案。

  • 顯示快取文字檔的內容。

若要建立快取物件

  1. 按兩下您剛才新增的按鈕,以在 MainWindow.xaml.cs 或 MainWindow.Xaml.vb 檔案中建立事件處理常式。

  2. 在檔案頂端(在類別宣告之前),新增下列 Imports (Visual Basic) 或 using (C#) 語句:

    using System.Runtime.Caching;
    using System.IO;
    
    Imports System.Runtime.Caching
    Imports System.IO
    
  3. 在事件處理常式中,新增下列程式碼來具現化快取物件:

    ObjectCache cache = MemoryCache.Default;
    
    Dim cache As ObjectCache = MemoryCache.Default
    

    類別 ObjectCache 是內建類別,可提供記憶體內建物件快取。

  4. 新增下列程式碼,以讀取名為 filecontents 的快取專案內容:

    Dim fileContents As String = TryCast(cache("filecontents"), String)
    
    string fileContents = cache["filecontents"] as string;
    
  5. 新增下列程式碼來檢查名為 filecontents 的快取專案是否存在:

    If fileContents Is Nothing Then
    
    End If
    
    if (fileContents == null)
    {
    
    }
    

    如果指定的快取專案不存在,您必須讀取文字檔,並將它新增為快取專案的快取專案。

  6. 在 區塊中 if/then ,新增下列程式碼來建立新的 CacheItemPolicy 物件,指定快取專案在 10 秒後到期。

    Dim policy As New CacheItemPolicy()
    policy.AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(10.0)
    
    CacheItemPolicy policy = new CacheItemPolicy();
    policy.AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(10.0);
    

    如果未提供收回或到期資訊,則預設值為 InfiniteAbsoluteExpiration ,這表示快取專案永遠不會根據絕對時間到期。 相反地,只有在記憶體壓力時,快取專案才會到期。 最佳做法是,您應該一律明確提供絕對或滑動到期。

  7. if/then 區塊內,並遵循您在上一個步驟中新增的程式碼,新增下列程式碼來建立您要監視之檔案路徑的集合,並將文字檔的路徑新增至集合:

    Dim filePaths As New List(Of String)()
    filePaths.Add("c:\cache\cacheText.txt")
    
    List<string> filePaths = new List<string>();
    filePaths.Add("c:\\cache\\cacheText.txt");
    

    注意

    如果您想要使用的文字檔不是 c:\cache\cacheText.txt ,請指定您要使用之文字檔的路徑。

  8. 在上一個步驟中新增的程式碼之後,新增下列程式碼,將新的 HostFileChangeMonitor 物件新增至快取專案的變更監視器集合:

    policy.ChangeMonitors.Add(New HostFileChangeMonitor(filePaths))
    
    policy.ChangeMonitors.Add(new HostFileChangeMonitor(filePaths));
    

    HostFileChangeMonitor物件會監視文字檔的路徑,並在發生變更時通知快取。 在此範例中,如果檔案的內容變更,快取專案將會過期。

  9. 在上一個步驟中新增的程式碼之後,新增下列程式碼以讀取文字檔的內容:

    fileContents = File.ReadAllText("c:\cache\cacheText.txt") & vbCrLf & DateTime.Now.ToString()
    
    fileContents = File.ReadAllText("c:\\cache\\cacheText.txt") + "\n" + DateTime.Now;
    

    新增日期和時間時間戳記,讓您可以在快取專案到期時看到。

  10. 在上一個步驟中新增的程式碼之後,新增下列程式碼,將檔案的內容插入快取物件中做為 CacheItem 實例:

    cache.Set("filecontents", fileContents, policy)
    
    cache.Set("filecontents", fileContents, policy);
    

    您可以藉由傳遞 CacheItemPolicy 您稍早建立的物件做為參數,指定快取專案應如何收回的相關資訊。

  11. if/then 區塊之後,新增下列程式碼,以在訊息方塊中顯示快取的檔案內容:

    MessageBox.Show(fileContents)
    
    MessageBox.Show(fileContents);
    
  12. 在 [ 建置] 功能表中,按一下 [建置 WPFCaching ] 來建置專案。

在 WPF 應用程式中測試快取

您現在可以測試應用程式。

在 WPF 應用程式中測試快取

  1. 按 CTRL+F5 執行應用程式。

    視窗 MainWindow 隨即顯示。

  2. 按一下 [ 取得快取 ]。

    文字檔的快取內容會顯示在訊息方塊中。 請注意檔案上的時間戳記。

  3. 關閉訊息方塊,然後按一下 [再次取得快取 ]。

    時間戳記不會變更。 這表示快取的內容已顯示。

  4. 等候 10 秒以上,然後按一下 [再次取得快取 ]。

    這次會顯示新的時間戳記。 這表示原則會讓快取專案過期,並顯示新的快取內容。

  5. 在文字編輯器中,開啟您建立的文字檔。 尚未進行任何變更。

  6. 關閉訊息方塊,然後按一下 [再次取得快取 ]。

    再次注意時間戳記。

  7. 對文字檔進行變更,然後儲存檔案。

  8. 關閉訊息方塊,然後按一下 [再次取得快取 ]。

    此訊息方塊包含文字檔中更新的內容,以及新的時間戳記。 這表示當您變更檔案時,主機檔案變更監視器會立即收回快取專案,即使絕對逾時期間尚未過期也一樣。

    注意

    您可以將收回時間增加到 20 秒以上,以允許更多時間讓您在檔案中進行變更。

程式碼範例

完成本逐步解說之後,您建立之專案的程式碼會類似下列範例。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Runtime.Caching;
using System.IO;

namespace WPFCaching
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {

            ObjectCache cache = MemoryCache.Default;
            string fileContents = cache["filecontents"] as string;

            if (fileContents == null)
            {
                CacheItemPolicy policy = new CacheItemPolicy();
                policy.AbsoluteExpiration =
                    DateTimeOffset.Now.AddSeconds(10.0);

                List<string> filePaths = new List<string>();
                filePaths.Add("c:\\cache\\cacheText.txt");

                policy.ChangeMonitors.Add(new
                    HostFileChangeMonitor(filePaths));

                // Fetch the file contents.
                fileContents = File.ReadAllText("c:\\cache\\cacheText.txt") + "\n" + DateTime.Now.ToString();

                cache.Set("filecontents", fileContents, policy);
            }
            MessageBox.Show(fileContents);
        }
    }
}
Imports System.Runtime.Caching
Imports System.IO

Class MainWindow

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click
        Dim cache As ObjectCache = MemoryCache.Default
        Dim fileContents As String = TryCast(cache("filecontents"), _
            String)

        If fileContents Is Nothing Then
            Dim policy As New CacheItemPolicy()
            policy.AbsoluteExpiration = _
                DateTimeOffset.Now.AddSeconds(10.0)
            Dim filePaths As New List(Of String)()
            filePaths.Add("c:\cache\cacheText.txt")
            policy.ChangeMonitors.Add(New  _
                HostFileChangeMonitor(filePaths))

            ' Fetch the file contents.
            fileContents = File.ReadAllText("c:\cache\cacheText.txt") & vbCrLf & DateTime.Now.ToString()
            cache.Set("filecontents", fileContents, policy)
        End If
        MessageBox.Show(fileContents)
    End Sub
End Class

另請參閱