次の方法で共有


チュートリアル: WPF アプリケーションでのアプリケーション データのキャッシュ

キャッシュを使用すると、高速アクセスのためにデータをメモリに格納できます。 データに再度アクセスすると、アプリケーションは元のソースからデータを取得するのではなく、キャッシュからデータを取得できます。 これにより、パフォーマンスとスケーラビリティが向上します。 さらに、キャッシュを使用すると、データ ソースが一時的に使用できないときにデータを使用できるようになります。

.NET Framework には、.NET Framework アプリケーションでキャッシュを使用できるクラスが用意されています。 これらのクラスは、 System.Runtime.Caching 名前空間にあります。

System.Runtime.Caching名前空間は、.NET Framework 4 の新機能です。 この名前空間により、すべての .NET Framework アプリケーションでキャッシュを使用できるようになります。 以前のバージョンの .NET Framework では、キャッシュは System.Web 名前空間でのみ使用できるため、ASP.NET クラスへの依存関係が必要でした。

このチュートリアルでは、Windows Presentation Foundation (WPF) アプリケーションの一部として .NET Framework で使用できるキャッシュ機能を使用する方法について説明します。 このチュートリアルでは、テキスト ファイルの内容をキャッシュします。

このチュートリアルで説明するタスクは次のとおりです。

  • 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. OK をクリックします。

    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 名前空間への参照を追加します。

.NET Framework ターゲットを変更する手順は、Visual Basic プロジェクトと Visual C# プロジェクトでは異なります。

Visual Basic でターゲットの .NET Framework を変更するには

  1. ソリューション エクスプローラーで、プロジェクト名を右クリックし、[プロパティ] をクリックします。

    アプリケーションのプロパティ ウィンドウが表示されます。

  2. [コンパイル] タブをクリックします。

  3. ウィンドウの下部にある [ 高度なコンパイル オプション...] をクリックします。

    [ コンパイラの詳細設定] ダイアログ ボックスが表示されます。

  4. ターゲット フレームワーク (すべての構成) の一覧で、.NET Framework 4 を選択します。 (.NET Framework 4 クライアント プロファイルは選択しないでください)。

  5. OK をクリックします。

    [ ターゲット フレームワークの変更 ] ダイアログ ボックスが表示されます。

  6. [ ターゲット フレームワークの変更 ] ダイアログ ボックスで、[ はい] をクリックします。

    プロジェクトは閉じられ、再度開きます。

  7. 次の手順に従って、キャッシュ アセンブリへの参照を追加します。

    1. ソリューション エクスプローラーで、プロジェクトの名前を右クリックし、[参照の追加] をクリックします。

    2. [.NET] タブを選択し、[System.Runtime.Caching] を選択し、[OK] をクリックします。

Visual C# プロジェクトでターゲットの .NET Framework を変更するには

  1. ソリューション エクスプローラーで、プロジェクト名を右クリックし、[プロパティ] をクリックします。

    アプリケーションのプロパティ ウィンドウが表示されます。

  2. [ アプリケーション ] タブをクリックします。

  3. ターゲット フレームワークの一覧で、.NET Framework 4 を選択します。 ( .NET Framework 4 クライアント プロファイルは選択しないでください)。

  4. 次の手順に従って、キャッシュ アセンブリへの参照を追加します。

    1. [ 参照 ] フォルダーを右クリックし、[ 参照の追加] をクリックします。

    2. [.NET] タブを選択し、[System.Runtime.Caching] を選択し、[OK] をクリックします。

WPF ウィンドウへのボタンの追加

次に、ボタン コントロールを追加し、ボタンの Click イベントのイベント ハンドラーを作成します。 後でコードを追加して、ボタンをクリックするとテキスト ファイルの内容がキャッシュされて表示されるようにします。

ボタン コントロールを追加するには

  1. ソリューション エクスプローラーで、MainWindow.xaml ファイルをダブルクリックして開きます。

  2. ツールボックスの [共通 WPF コントロール] で、Button コントロールを MainWindow ウィンドウにドラッグします。

  3. [プロパティ] ウィンドウで、Content コントロールの Button プロパティを [キャッシュの取得] に設定します。

キャッシュの初期化とエントリのキャッシュ

次に、次のタスクを実行するコードを追加します。

  • キャッシュ クラスのインスタンスを作成します。つまり、新しい 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 ブロックで、次のコードを追加して、キャッシュ エントリが 10 秒後に期限切れであることを指定する新しいCacheItemPolicy オブジェクトを作成します。

    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

こちらも参照ください