0

アプリケーション キャッシュを使用して、ASP.net 3.5 Web サイトにアプリケーション全体のフィードを作成したいと考えています。キャッシュに入力するために使用しているデータの取得は遅く、おそらく最大 10 秒 (リモート サーバーのデータ フィードから) です。私の質問/混乱は、キャッシュ管理を構築するための最良の方法は何かということです。

private const string CacheKey = "MyCachedString";
private static string lockString = "";

public string GetCachedString()
{
    string data = (string)Cache[CacheKey];
    string newData = "";

    if (data == null)
    {
        // A - Should this method call go here?
        newData = SlowResourceMethod();

        lock (lockString)
        {
            data = (string)Cache[CacheKey];

            if (data != null)
            {
               return data;
            }

            // B - Or here, within the lock?
            newData = SlowResourceMethod();
            Cache[CacheKey] = data = newData;
        }
    }

    return data;
}

実際のメソッドは、HttpHandler (.ashx) によって提示されます。

ポイント「A」でデータを収集すると、ロック時間を短く保ちますが、外部リソースを何度も呼び出すことになる可能性があります (すべての Web ページからフィードを参照しようとします)。ポイント「B」に置くと、ロック時間が長くなりますが、これは悪いことだと思います。

最善のアプローチは何ですか、または使用できるより良いパターンはありますか?

アドバイスをいただければ幸いです。

4

1 に答える 1

1

コードにコメントを追加します。

private const string CacheKey = "MyCachedString";
private static readonly object syncLock = new object();

public string GetCachedString()
{
    string data = (string)Cache[CacheKey];
    string newData = "";

    // start to check if you have it on cache
    if (data == null)
    {
        // A - Should this method call go here?
        // absolut not here
        // newData = SlowResourceMethod();

        // we are now here and wait for someone else to make it or not
        lock (syncLock)
        {
            // now lets see if some one else make it...
            data = (string)Cache[CacheKey];

            // we have it, send it
            if (data != null)
            {
               return data;
            }

            // not have it, now is the time to look for it.
            // B - Or here, within the lock?
            newData = SlowResourceMethod();
            // set it on cache
            Cache[CacheKey] = data = newData;
        }
    }

    return data;
}

mutex私にとっては、名前に応じて使用およびロックし、CacheKeyすべてのリソースと非相対リソースをロックしない方がよいでしょう。ミューテックスを使用すると、基本的な簡単な例の 1 つが次のようになります。

private const string CacheKey = "MyCachedString";
public string GetCachedString()
{
    string data = (string)Cache[CacheKey];
    string newData = "";

    // start to check if you have it on cache
    if (data == null)
    {
        // lock it base on resource key 
        //  (note that not all chars are valid for name)
        var mut = new Mutex(true, CacheKey);

        try
        {   
            // Wait until it is safe to enter.
            // but also add 30 seconds max
            mut.WaitOne(30000);

            // now lets see if some one else make it...
            data = (string)Cache[CacheKey];

            // we have it, send it
            if (data != null)
            {
               return data;
            }

            // not have it, now is the time to look for it.
            // B - Or here, within the lock?
            newData = SlowResourceMethod();
            // set it on cache
            Cache[CacheKey] = data = newData;

        }
        finally
        {
            // Release the Mutex.
            mut.ReleaseMutex();
        }    
    }

    return data;
}

ASP.NET のファイルを使用して、イメージ キャッシュの問題を読み取ることもできます。

于 2013-06-06T12:21:49.127 に答える