ASP.NETキャッシュの実装と応用

概要

ASP.NETにおけるキャッシュ技術はアプリケーション性能を向上させる重要な機能です。複雑なクエリ処理時のデータをメモリに保存することで、後続のリクエストにおいてDBアクセスを回避できます。主に以下の2つのキャッシュ方式が利用可能です:

  1. 出力キャッシュ(Output Caching)

  2. データキャッシュ(Data Caching)

  3. 出力キャッシュ(Output Caching)


出力キャッシュはHTML出力を直接保存する仕組みで、同じページリクエストに対してサーバー側の処理をスキップします。以下が基本構文です:

<%@ OutputCache Duration="60" VaryByParam="None" %>

Duration属性で60秒間キャッシュを保持し、VaryByParamはパラメータ変化によるキャッシュ分離を制御します。以下は実装例です:

<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="OutputCachingDemo.aspx.cs" Inherits="OutputCachingDemo" Title="キャッシュテスト" %>
<%@ OutputCache Duration="20" VaryByParam="None" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
  <div class="header">出力キャッシュデモ</div>
  日付: <asp:Label ID="txtDate" runat="server" Text="" />
  時刻: <asp:Label ID="txtTime" runat="server" Text="" />
</asp:Content>

コードビハインド:

protected void Page_Load(object sender, EventArgs e)
{
    txtDate.Text = DateTime.Now.ToShortDateString();
    txtTime.Text = DateTime.Now.ToLongTimeString();
}

クエリ文字列ベースキャッシュ

動的パラメータ対応にはVaryByParam属性を活用します:

<%@ OutputCache Duration="60" VaryByParam="*" %>
<div align="right">
  <a href="OutputCachingDemo2.aspx">基本表示</a> | 
  <a href="OutputCachingDemo2.aspx?user=101">ユーザー101</a> | 
  <a href="OutputCachingDemo2.aspx?user=102">ユーザー102</a>
</div>

特定パラメータ指定時は以下のように記述します:

<%@ OutputCache Duration="60" VaryByParam="user;lang" %>

カスタムキャッシュロジック

global.asaxに以下のようなカスタムロジックを実装可能です:

public override string GetCustomVaryString(HttpContext context, string key)
{
    if(key == "browser")
    {
        return $"{context.Request.Browser.Browser}_{context.Request.Browser.MajorVersion}";
    }
    return base.GetCustomVaryString(context, key);
}

コントロール単位キャッシュ

個別コントロールのキャッシュはVaryByControl属性で指定します:

<%@ OutputCache Duration="20" VaryByControl="UserInfoControl" %>

.ascxファイル内では:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="UserInfo.ascx.cs" Inherits="UserInfo" %>
<%@ OutputCache Duration="20" VaryByControl="UserID" %>

コードビハインド:

private int _userId;
public int UserID
{
    get { return _userId; }
    set { _userId = value; }
}

protected void Page_Load(object sender, EventArgs e)
{
    txtDate.Text = DateTime.Now.ToShortDateString();
    txtTime.Text = DateTime.Now.ToLongTimeString();
    lblUser.Text = UserID.ToString();
}

キャッシュプロファイル設定

web.configでの設定例:

<system.web>
  <caching>
    <outputCacheSettings>
      <outputCacheProfiles>
        <add name="ProductCache" duration="60"/>
      </outputCacheProfiles>
    </outputCacheSettings>
  </caching>
</system.web>

利用例:

<%@ OutputCache CacheProfile="ProductCache" VaryByParam="None" %>

2. データキャッシュ(Data Caching)

時間のかかる処理結果をキャッシュするには以下のような方法を使用します:

DateTime cachedTime = DateTime.Now;
Cache.Insert("CachedTimestamp", cachedTime, null, DateTime.Now.AddSeconds(20), TimeSpan.Zero);

キャッシュ依存性

他のキャッシュ項目に依存する設定は以下のように行います:

string[] dependencies = { "CachedTimestamp" };
CacheDependency dep = new CacheDependency(null, dependencies);
Cache.Insert("CachedDateTime", DateTime.Now, dep);

キャッシュコールバック機能

キャッシュ削除時にコールバックを登録する例:

protected void Page_Load(object sender, EventArgs e)
{
    DateTime? time1 = (DateTime?)Cache["CachedTimestamp"];
    if (!time1.HasValue)
    {
        time1 = DateTime.Now;
        Cache.Insert("CachedTimestamp", time1, null, DateTime.Now.AddSeconds(20), TimeSpan.Zero,
                     CacheItemPriority.Default, OnCacheItemRemoved);
    }

    DateTime? time2 = (DateTime?)Cache["CachedDateTime"];
    if (!time2.HasValue)
    {
        time2 = DateTime.Now;
        Cache.Insert("CachedDateTime", time2, null, DateTime.Now.AddSeconds(40), TimeSpan.Zero,
                     CacheItemPriority.Default, OnCacheItemRemoved);
    }

    txtDate.Text = time1.Value.ToShortDateString();
    txtTime.Text = time1.Value.ToLongTimeString();
    txtDate1.Text = time2.Value.ToShortDateString();
    txtTime1.Text = time2.Value.ToLongTimeString();
}

private void OnCacheItemRemoved(string key, object value, CacheItemRemovedReason reason)
{
    if (key == "CachedTimestamp" || key == "CachedDateTime")
    {
        Cache.Remove("CachedTimestamp");
        Cache.Remove("CachedDateTime");
    }
}

タグ: ASP.NET キャッシュ最適化 Webアプリケーション HTTPキャッシュ メモリ管理

5月23日 08:27 投稿