チュートリアル: 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 に参照を追加します。
キャッシュを初期化します。
テキスト ファイルの内容を格納しているキャッシュ エントリを追加します。
キャッシュ エントリの削除ポリシーを指定します。
キャッシュ ファイルのパスを監視し、監視対象の項目への変更についてキャッシュ インスタンスに通知します。
必須コンポーネント
このチュートリアルを完了するための要件は次のとおりです。
Microsoft Visual Studio 2010
少量のテキストを含むテキスト ファイル。 このテキスト ファイルの内容をメッセージ ボックスに表示します。 このチュートリアルに示すコードでは、次のファイルを使用していることを前提としています。
c:\cache\cacheText.txt
ただし、このチュートリアルでは、任意のテキスト ファイルを使用し、コードにわずかな変更を加えることができます。
WPF アプリケーション プロジェクトの作成
WPF アプリケーション プロジェクトを作成することから始めます。
WPF アプリケーションを作成するには
Visual Studio を起動します。
[ファイル] メニューの [新規作成] をクリックし、[新しいプロジェクト] をクリックします。
[新しいプロジェクト] ダイアログ ボックスが表示されます。
[インストールされているテンプレート] で、使用するプログラミング言語 ([Visual Basic] または [Visual C#]) をクリックします。
[新しいプロジェクト] ダイアログ ボックスで、[WPF アプリケーション] をクリックします。
メモ [WPF アプリケーション] テンプレートがない場合は、WPF をサポートしている .NET Framework のバージョンを使用しているかどうかを確認してください。[新しいプロジェクト] ダイアログ ボックスで、一覧から .NET Framework 4 を選択します。
[名前] ボックスにプロジェクトの名前を入力します。 たとえば、「WPFCaching」と入力できます。
[ソリューションのディレクトリを作成] チェック ボックスをオンにします。
[OK] をクリックします。
デザイン ビューに WPF デザイナーが開き、MainWindow.xaml ファイルが表示されます。 Visual Studio では、My Project フォルダー、Application.xaml ファイル、および MainWindow.xaml ファイルを作成します。
.NET Framework を対象にすることおよびキャッシュ アセンブリへの参照の追加
既定では、WPF アプリケーションは .NET Framework 4 Client Profile を対象とします。 WPF アプリケーションで System.Runtime.Caching 名前空間を使用するには、名前空間で .NET Framework 4 (.NET Framework 4 Client Profile ではない) を対象にして、名前空間への参照を含める必要があります。
そのため、次の手順では対象の .NET Framework を変更し、System.Runtime.Caching 名前空間への参照を追加します。
メモ |
---|
Visual Basic プロジェクトと Visual C# プロジェクトでは、対象の .NET Framework を変更する手順が異なります。 |
Visual Basic で対象の .NET Framework を変更するには
ソリューション エクスプローラーで、プロジェクト名を右クリックし、[プロパティ] をクリックします。
アプリケーションのプロパティ ウィンドウが表示されます。
[コンパイル] タブをクリックします。
ウィンドウの下部にある [詳細コンパイル オプション] をクリックします。
[コンパイラの詳細設定] ダイアログ ボックスが表示されます。
[対象のフレームワーク (すべての構成)] ボックスの一覧で、.NET Framework 4 を選択します (.NET Framework 4 Client Profile は選択しないでください)。
[OK] をクリックします。
[対象とする Framework の変更] ダイアログ ボックスが表示されます。
[対象とする Framework の変更] ダイアログ ボックスで、[はい] をクリックします。
プロジェクトが閉じてから再び開きます。
次の手順に従って、キャッシュ アセンブリへの参照を追加します。
ソリューション エクスプローラーで、プロジェクトの名前を右クリックし、[参照の追加] をクリックします。
[.NET] タブをクリックし、System.Runtime.Caching を選択して、[OK] をクリックします。
Visual C# プロジェクトで対象の .NET Framework を変更するには
ソリューション エクスプローラーで、プロジェクト名を右クリックし、[プロパティ] をクリックします。
アプリケーションのプロパティ ウィンドウが表示されます。
[アプリケーション] タブをクリックします。
[対象とする Framework] ボックスの一覧で、.NET Framework 4 を選択します (.NET Framework 4 Client Profile は選択しないでください)。
次の手順に従って、キャッシュ アセンブリへの参照を追加します。
[参照設定] フォルダーを右クリックし、[参照の追加] をクリックします。
[.NET] タブをクリックし、System.Runtime.Caching を選択して、[OK] をクリックします。
WPF ウィンドウへのボタンの追加
次に、ボタン コントロールを追加して、ボタンの Click イベントのイベント ハンドラーを作成します。 後でコードを追加し、ボタンをクリックしたときにテキスト ファイルの内容がキャッシュされて表示されるようにします。
ボタン コントロールを追加するには
ソリューション エクスプローラーで、MainWindow.xaml ファイルをダブルクリックして開きます。
[ツールボックス] の [コモン WPF コントロール] で、Button コントロールを MainWindow ウィンドウにドラッグします。
プロパティ ウィンドウで、Button コントロールの Content プロパティを [Get Cache] に設定します。
キャッシュの初期化とエントリのキャッシュ
次に、次のタスクを行うコードを追加します。
キャッシュ クラスのインスタンスを作成します。つまり、新しい MemoryCache オブジェクトのインスタンスを生成します。
キャッシュが HostFileChangeMonitor オブジェクトを使用してテキスト ファイルの変更を監視するよう指定します。
テキスト ファイルを読み取り、その内容をキャッシュ エントリとしてキャッシュします。
キャッシュしたテキスト ファイルの内容を表示します。
キャッシュ オブジェクトを作成するには
MainWindow.xaml.cs ファイルまたは MainWindow.Xaml.vb ファイルにイベント ハンドラーを作成するために、追加したボタンをダブルクリックします。
ファイルの上部 (クラス宣言の前) に次の Imports (Visual Basic) または using (C#) ステートメントを追加します。
using System.Runtime.Caching; using System.IO;
Imports System.Runtime.Caching Imports System.IO
キャッシュ オブジェクトのインスタンスを生成するためにイベント ハンドラーに次のコードを追加します。
ObjectCache cache = MemoryCache.Default;
Dim cache As ObjectCache = MemoryCache.Default
ObjectCache クラスは、メモリ内オブジェクト キャッシュを提供する組み込みクラスです。
filecontents という名前のキャッシュ エントリの内容を読み取るために次のコードを追加します。
Dim fileContents As String = TryCast(cache("filecontents"), String)
string fileContents = cache["filecontents"] as string;
filecontents という名前のキャッシュ エントリがあるかどうかを確認するために次のコードを追加します。
If fileContents Is Nothing Then End If
if (fileContents == null) { }
指定したキャッシュ エントリがない場合は、テキスト ファイルを読み取り、これをキャッシュ エントリとしてキャッシュに追加する必要があります。
キャッシュ エントリの有効期限が 10 秒後に切れるように指定する新しい CacheItemPolicy オブジェクトを作成するために、if/then ブロックに次のコードを追加します。
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/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 でない場合は、そのテキスト ファイルのパスを指定します。
キャッシュ エントリの変更監視機能のコレクションに新しい HostFileChangeMonitor オブジェクトを追加するために、前の手順で追加したコードの後に次のコードを追加します。
policy.ChangeMonitors.Add(New HostFileChangeMonitor(filePaths))
policy.ChangeMonitors.Add(new HostFileChangeMonitor(filePaths));
HostFileChangeMonitor オブジェクトはテキスト ファイルのパスを監視し、変更が発生するとキャッシュに通知します。 この例のキャッシュ エントリは、ファイルの内容に変更があると有効期限が切れます。
テキスト ファイルの内容を読み取るために、前の手順で追加したコードの後に次のコードを追加します。
fileContents = File.ReadAllText("c:\cache\cacheText.txt") & vbCrLf & DateTime.Now.ToString()
fileContents = File.ReadAllText("c:\\cache\\cacheText.txt") + + "\n" + DateTime.Now;
キャッシュ エントリの有効期限を確認できるように、日付と時刻のタイムスタンプが追加されます。
ファイルの内容を CacheItem インスタンスとしてキャッシュ オブジェクトに挿入するために、前の手順で追加したコードの後に次のコードを追加します。
cache.Set("filecontents", fileContents, policy)
cache.Set("filecontents", fileContents, policy);
キャッシュ エントリの削除方法に関する情報を指定するために、前に作成した CacheItemPolicy オブジェクトをパラメーターとして渡します。
キャッシュしたファイルの内容をメッセージ ボックスに表示するために、if/then ブロックの後に次のコードを追加します。
MessageBox.Show(fileContents)
MessageBox.Show(fileContents);
[ビルド] メニューの [WPFCaching のビルド] をクリックし、プロジェクトをビルドします。
WPF アプリケーションでのキャッシュのテスト
これで、アプリケーションをテストできるようになりました。
WPF アプリケーションでのキャッシュをテストするには
Ctrl キーを押しながら F5 キーを押してアプリケーションを実行します。
MainWindow ウィンドウが表示されます。
[Get Cache] をクリックします。
テキスト ファイルのキャッシュされた内容がメッセージ ボックスに表示されます。 ファイルにタイムスタンプがあることを確認します。
メッセージ ボックスを閉じてから、[Get Cache] を再度クリックします。
タイムスタンプは変わりません。 これは、キャッシュされた内容が表示されていることを示します。
10 秒以上待機してから、[Get Cache] を再度クリックします。
今度は新しいタイムスタンプが表示されます。 これはポリシーによってキャッシュ エントリの有効期限が切れ、キャッシュされた新しい内容が表示されていることを示します。
テキスト エディターで、作成したテキスト ファイルを開きます。 まだ変更は加えないでください。
メッセージ ボックスを閉じてから、[Get Cache] を再度クリックします。
タイムスタンプを再度確認します。
テキスト ファイルに変更を加え、ファイルを保存します。
メッセージ ボックスを閉じてから、[Get Cache] を再度クリックします。
このメッセージ ボックスには、テキスト ファイルの更新された内容と新しいタイムスタンプが格納されます。 これは、絶対タイムアウト期間が期限切れではない場合でも、ファイルを変更したときにホスト ファイルの変更監視機能によってキャッシュ エントリが直ちに削除されたことを示します。
メモ 削除時間を 20 秒以上に長くすると、ファイルに変更を加える時間を長くすることができます。
コード例
このチュートリアルを完了すると、作成したプロジェクトのコードは次の例のようになります。
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
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);
}
}
}