演练:在 WPF 应用程序中缓存应用程序数据Walkthrough: Caching Application Data in a WPF Application

缓存可以将数据存储在内存中以便快速访问。Caching enables you to store data in memory for rapid access. 再次访问数据时,应用程序可以从缓存获取数据,而不是从原始源检索数据。When the data is accessed again, applications can get the data from the cache instead of retrieving it from the original source. 这可改善性能和可伸缩性。This can improve performance and scalability. 此外,数据源暂时不可用时,缓存可提供数据。In addition, caching makes data available when the data source is temporarily unavailable.

.NET Framework 提供使你能够在 .NET Framework 应用程序中使用缓存的类。The .NET Framework provides classes that enable you to use caching in .NET Framework applications. 这些类位于 System.Runtime.Caching 命名空间中。These classes are located in the System.Runtime.Caching namespace.

备注

System.Runtime.Caching 命名空间是 .NET Framework 4 中的新命名空间。The System.Runtime.Caching namespace is new in the .NET Framework 4. 此命名空间使缓存可供所有 .NET Framework 应用程序使用。This namespace makes caching is available to all .NET Framework applications. 在以前版本的 .NET Framework 中,只能在 System.Web 命名空间中使用缓存,因此需要依赖 ASP.NET 类。In previous versions of the .NET Framework, caching was available only in the System.Web namespace and therefore required a dependency on ASP.NET classes.

本演练演示如何使用 .NET Framework 中提供的缓存功能作为 Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) 应用程序的一部分。This walkthrough shows you how to use the caching functionality that is available in the .NET Framework as part of a Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) application. 在本演练中,您将缓存文本文件的内容。In the walkthrough, you cache the contents of a text file.

本演练演示以下任务:Tasks illustrated in this walkthrough include the following:

  • 创建 WPF 应用程序项目。Creating a WPF application project.

  • 添加对 .NET Framework 4 的引用。Adding a reference to the .NET Framework 4.

  • 初始化缓存。Initializing a cache.

  • 添加包含文本文件内容的缓存项。Adding a cache entry that contains the contents of a text file.

  • 为缓存条目提供逐出策略。Providing an eviction policy for the cache entry.

  • 监视缓存文件的路径,并通知缓存实例对被监视项的更改。Monitoring the path of the cached file and notifying the cache instance about changes to the monitored item.

先决条件Prerequisites

为了完成本演练,您需要:In order to complete this walkthrough, you will need:

  • Visual Studio 2010。Visual Studio 2010.

  • 包含少量文本的文本文件。A text file that contains a small amount of text. (将在消息框中显示文本文件的内容。)本演练中所示的代码假设您正在使用以下文件:(You will display the contents of the text file in a message box.) The code illustrated in the walkthrough assumes that you are working with the following file:

    c:\cache\cacheText.txt

    但是,您可以使用任何文本文件并对此演练中的代码进行较小的更改。However, you can use any text file and make small changes to the code in this walkthrough.

创建 WPF 应用程序项目Creating a WPF Application Project

首先创建一个 WPF 应用程序项目。You will start by creating a WPF application project.

创建 WPF 应用程序To create a WPF application

  1. 启动 Visual Studio。Start Visual Studio.

  2. 在 "文件" 菜单中,单击 "新建",然后单击 "新建项目"。In the File menu, click New, and then click New Project.

    显示 “新项目” 对话框。The New Project dialog box is displayed.

  3. 在 "已安装的模板" 下,选择要使用的编程语言(Visual Basic视觉对象C# )。Under Installed Templates, select the programming language you want to use (Visual Basic or Visual C#).

  4. 在 "新建项目" 对话框中,选择 " WPF 应用程序"。In the New Project dialog box, select WPF Application.

    备注

    如果看不到 " Wpf 应用程序" 模板,请确保以支持 WPF 的 .NET Framework 的版本为目标。If you do not see the WPF Application template, make sure that you are targeting a version of the .NET Framework that supports WPF. 在 "新建项目" 对话框中,从列表中选择 ".NET Framework 4"。In the New Project dialog box, select .NET Framework 4 from the list.

  5. 在 "名称" 文本框中,输入项目的名称。In the Name text box, enter a name for your project. 例如,可以输入WPFCachingFor example, you can enter WPFCaching.

  6. 选择“为解决方案创建目录”复选框。Select the Create directory for solution check box.

  7. 单击“确定”。Click OK.

    WPF 设计器将在 "设计" 视图中打开并显示 mainwindow.xaml 文件。The WPF Designer opens in Design view and displays the MainWindow.xaml file. Visual Studio 将创建 "我的项目" 文件夹、应用程序 .xaml 文件和 mainwindow.xaml 文件。Visual Studio creates the My Project folder, the Application.xaml file, and the MainWindow.xaml file.

针对 .NET Framework 并添加对缓存程序集的引用Targeting the .NET Framework and Adding a Reference to the Caching Assemblies

默认情况下,WPF 应用程序以 .NET Framework 4 客户端配置文件为目标。By default, WPF applications target the .NET Framework 4 Client Profile. 若要在 WPF 应用程序中使用 System.Runtime.Caching 命名空间,应用程序必须以 .NET Framework 4 (而不是 .NET Framework 4 客户端配置文件)为目标,并且必须包括对命名空间的引用。To use the System.Runtime.Caching namespace in a WPF application, the application must target the .NET Framework 4 (not the .NET Framework 4 Client Profile) and must include a reference to the namespace.

因此,下一步是更改 .NET Framework 目标并添加对 System.Runtime.Caching 命名空间的引用。Therefore, the next step is to change the .NET Framework target and add a reference to the System.Runtime.Caching namespace.

备注

Visual Basic 项目和可视化C#项目中更改 .NET Framework 目标的过程有所不同。The procedure for changing the .NET Framework target is different in a Visual Basic project and in a Visual C# project.

更改目标 .NET Framework Visual BasicTo change the target .NET Framework in Visual Basic

  1. 在 "解决方案资源管理器" 中,右键单击项目名称,然后单击 "属性"。In Solutions Explorer, right-click the project name, and then click Properties.

    将显示应用程序的 "属性" 窗口。The properties window for the application is displayed.

  2. 单击“编译”选项卡。Click the Compile tab.

  3. 在窗口底部,单击 "高级编译选项 ... "。At the bottom of the window, click Advanced Compile Options….

    将显示 "高级编译器设置" 对话框。The Advanced Compiler Settings dialog box is displayed.

  4. 在 "目标框架(所有配置) " 列表中,选择 ".NET Framework 4"。In the Target framework (all configurations) list, select .NET Framework 4. (请勿选择 .NET Framework 4 客户端配置文件。)(Do not select .NET Framework 4 Client Profile.)

  5. 单击“确定”。Click OK.

    随即显示“目标框架更改”对话框。The Target Framework Change dialog box is displayed.

  6. 在 "目标框架更改" 对话框中,单击 "是"In the Target Framework Change dialog box, click Yes.

    项目已关闭,然后重新打开。The project is closed and is then reopened.

  7. 按照以下步骤添加对缓存程序集的引用:Add a reference to the caching assembly by following these steps:

    1. 解决方案资源管理器中,右键单击项目名称,然后单击 "添加引用"。In Solution Explorer, right-click the name of the project and then click Add Reference.

    2. 选择 " .net " 选项卡,选择 "System.Runtime.Caching",然后单击 "确定"Select the .NET tab, select System.Runtime.Caching, and then click OK.

更改可视化C#项目中的目标 .NET FrameworkTo change the target .NET Framework in a Visual C# project

  1. 解决方案资源管理器中,右键单击项目名称,然后单击 "属性"。In Solution Explorer, right-click the project name and then click Properties.

    将显示应用程序的 "属性" 窗口。The properties window for the application is displayed.

  2. 单击“应用程序” 选项卡。Click the Application tab.

  3. 在 "目标框架" 列表中,选择 ".NET Framework 4"。In the Target framework list, select .NET Framework 4. (请勿选择 .NET Framework 4 客户端配置文件。)(Do not select .NET Framework 4 Client Profile.)

  4. 按照以下步骤添加对缓存程序集的引用:Add a reference to the caching assembly by following these steps:

    1. 右键单击 "引用" 文件夹,然后单击 "添加引用"。Right-click the References folder and then click Add Reference.

    2. 选择 " .net " 选项卡,选择 "System.Runtime.Caching",然后单击 "确定"Select the .NET tab, select System.Runtime.Caching, and then click OK.

将按钮添加到 WPF 窗口Adding a Button to the WPF Window

接下来,您将添加一个按钮控件,并为按钮的 Click 事件创建事件处理程序。Next, you will add a button control and create an event handler for the button's Click event. 稍后你将向添加代码,以便在单击按钮时,将缓存并显示文本文件的内容。Later you will add code to so when you click the button, the contents of the text file are cached and displayed.

添加按钮控件To add a button control

  1. 解决方案资源管理器中,双击 mainwindow.xaml 文件以将其打开。In Solution Explorer, double-click the MainWindow.xaml file to open it.

  2. 从 "工具箱" 的 "常用 WPF 控件" 下,将 "Button" 控件拖动到 "MainWindow" 窗口。From the Toolbox, under Common WPF Controls, drag a Button control to the MainWindow window.

  3. 在 "属性" 窗口中,将 Button 控件的 Content 属性设置为 "获取缓存"。In the Properties window, set the Content property of the Button control to Get Cache.

初始化缓存并缓存项Initializing the Cache and Caching an Entry

接下来,你将添加代码来执行以下任务:Next, you will add the code to perform the following tasks:

  • 创建缓存类的实例,即,将实例化新的 MemoryCache 对象。Create an instance of the cache class—that is, you will instantiate a new MemoryCache object.

  • 指定缓存使用 HostFileChangeMonitor 对象来监视文本文件中的更改。Specify that the cache uses a HostFileChangeMonitor object to monitor changes in the text file.

  • 读取文本文件并将其内容缓存为缓存条目。Read the text file and cache its contents as a cache entry.

  • 显示缓存的文本文件的内容。Display the contents of the cached text file.

创建缓存对象To create the cache object

  1. 双击刚才添加的按钮,以便在 MainWindow.xaml.cs 或 Mainwindow.xaml 文件中创建事件处理程序。Double-click the button you just added in order to create an event handler in the MainWindow.xaml.cs or MainWindow.Xaml.vb file.

  2. 在文件顶部(类声明之前),添加以下 Imports (Visual Basic)或 using (C#)语句:At the top of the file (before the class declaration), add the following Imports (Visual Basic) or using (C#) statements:

    using System.Runtime.Caching;
    using System.IO;
    
    Imports System.Runtime.Caching
    Imports System.IO
    
  3. 在事件处理程序中,添加以下代码以实例化缓存对象:In the event handler, add the following code to instantiate the cache object:

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

    ObjectCache 类是提供内存中对象缓存的内置类。The ObjectCache class is a built-in class that provides an in-memory object cache.

  4. 添加以下代码以读取名为 filecontents的缓存条目的内容:Add the following code to read the contents of a cache entry named filecontents:

    Dim fileContents As String = TryCast(cache("filecontents"), String)
    
    string fileContents = cache["filecontents"] as string;
    
  5. 添加以下代码以检查是否存在名为 filecontents 的缓存条目:Add the following code to check whether the cache entry named filecontents exists:

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

    如果指定的缓存项不存在,则必须读取文本文件并将其作为缓存项添加到缓存中。If the specified cache entry does not exist, you must read the text file and add it as a cache entry to the cache.

  6. if/then 块中,添加以下代码以创建新的 CacheItemPolicy 对象,该对象指定该缓存条目在10秒后过期。In the if/then block, add the following code to create a new CacheItemPolicy object that specifies that the cache entry expires after 10 seconds.

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

    如果未提供任何逐出或过期信息,则默认值为 InfiniteAbsoluteExpiration,这意味着缓存条目永远不会仅基于绝对时间过期。If no eviction or expiration information is provided, the default is InfiniteAbsoluteExpiration, which means the cache entries never expire based only on an absolute time. 相反,缓存项仅在存在内存压力时过期。Instead, cache entries expire only when there is memory pressure. 最佳做法是,应始终显式提供绝对或可调过期。As a best practice, you should always explicitly provide either an absolute or a sliding expiration.

  7. if/then 块中,在上一步中添加的代码后面,添加以下代码以创建要监视的文件路径的集合,并将文本文件的路径添加到集合中:Inside the if/then block and following the code you added in the previous step, add the following code to create a collection for the file paths that you want to monitor, and to add the path of the text file to the collection:

    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要使用的文本文件,请指定要使用的文本文件的路径。If the text file you want to use is not c:\cache\cacheText.txt, specify the path where the text file is that you want to use.

  8. 在上一步中添加的代码后面,添加以下代码,以将新的 HostFileChangeMonitor 对象添加到缓存项的更改监视器集合中:Following the code that you added in the previous step, add the following code to add a new HostFileChangeMonitor object to the collection of change monitors for the cache entry:

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

    HostFileChangeMonitor 对象监视文本文件的路径,并在发生更改时通知缓存。The HostFileChangeMonitor object monitors the text file's path and notifies the cache if changes occur. 在此示例中,如果文件的内容发生更改,缓存项将过期。In this example, the cache entry will expire if the content of the file changes.

  9. 在上一步中添加的代码后面,添加以下代码以读取文本文件的内容:Following the code that you added in the previous step, add the following code to read the contents of the text file:

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

    添加了日期和时间戳,以便您能够查看缓存条目的过期时间。The date and time timestamp is added so that you will be able to see when the cache entry expires.

  10. 在上一步中添加的代码后面,添加以下代码,以将文件内容作为 CacheItem 实例插入到缓存对象中:Following the code that you added in the previous step, add the following code to insert the contents of the file into the cache object as a CacheItem instance:

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

    通过将之前创建的 CacheItemPolicy 对象作为参数传递,来指定有关如何逐出缓存项的信息。You specify information about how the cache entry should be evicted by passing the CacheItemPolicy object that you created earlier as a parameter.

  11. if/then 块后,添加以下代码以在消息框中显示缓存的文件内容:After the if/then block, add the following code to display the cached file content in a message box:

    MessageBox.Show(fileContents)
    
    MessageBox.Show(fileContents);
    
  12. 在 "生成" 菜单中,单击 "生成 WPFCaching " 以生成项目。In the Build menu, click Build WPFCaching to build your project.

在 WPF 应用程序中测试缓存Testing Caching in the WPF Application

现在可以测试此应用程序。You can now test the application.

在 WPF 应用程序中测试缓存To test caching in the WPF application

  1. 按 Ctrl+F5 以运行应用程序。Press CTRL+F5 to run the application.

    将显示 "MainWindow" 窗口。The MainWindow window is displayed.

  2. 单击 "获取缓存"。Click Get Cache.

    文本文件中的缓存内容显示在一个消息框中。The cached content from the text file is displayed in a message box. 请注意该文件上的时间戳。Notice the timestamp on the file.

  3. 关闭消息框,然后再次单击 "获取缓存"。Close the message box and then click Get Cache again.

    时间戳未更改。The timestamp is unchanged. 这表示显示缓存内容。This indicates the cached content is displayed.

  4. 等待10秒钟或更多,然后再次单击 "获取缓存"。Wait 10 seconds or more and then click Get Cache again.

    此时将显示新的时间戳。This time a new timestamp is displayed. 这表示策略使缓存条目过期,并显示新的缓存内容。This indicates that the policy let the cache entry expire and that new cached content is displayed.

  5. 在文本编辑器中,打开您创建的文本文件。In a text editor, open the text file that you created. 不要进行任何更改。Do not make any changes yet.

  6. 关闭消息框,然后再次单击 "获取缓存"。Close the message box and then click Get Cache again.

    再次注意时间戳。Notice the timestamp again.

  7. 对文本文件进行更改,然后保存该文件。Make a change to the text file and then save the file.

  8. 关闭消息框,然后再次单击 "获取缓存"。Close the message box and then click Get Cache again.

    此消息框包含文本文件中的更新内容和新的时间戳。This message box contains the updated content from the text file and a new timestamp. 这表明在更改文件时,主机文件更改监视器会立即逐出缓存项,即使绝对超时期限尚未过期。This indicates that the host-file change monitor evicted the cache entry immediately when you changed the file, even though the absolute timeout period had not expired.

    备注

    你可以将逐出时间增加到20秒或更多,以允许更多的时间来对文件进行更改。You can increase the eviction time to 20 seconds or more to allow more time for you to make a change in the file.

代码示例Code Example

完成本演练后,你创建的项目的代码将与以下示例类似。After you have completed this walkthrough, the code for the project you created will resemble the following example.

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

另请参阅See also