Правильное выполнение блокировки в ASP.NET

У меня есть сайт ASP.NET с довольно медленной функцией поиска, и я хочу повысить производительность, добавляя результаты в кеш на один час, используя запрос в качестве ключа кеша:

using System;
using System.Web;
using System.Web.Caching;

public class Search
{
    private static object _cacheLock = new object();

    public static string DoSearch(string query)
    {
        string results = "";

        if (HttpContext.Current.Cache[query] == null)
        {
            lock (_cacheLock)
            {
                if (HttpContext.Current.Cache[query] == null)
                {
                    results = GetResultsFromSlowDb(query);

                    HttpContext.Current.Cache.Add(query, results, null, DateTime.Now.AddHours(1), Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);
                }
                else
                {
                    results = HttpContext.Current.Cache[query].ToString();
                }
            }
        }
        else
        {
            results = HttpContext.Current.Cache[query].ToString();
        }

        return results;
    }

    private static string GetResultsFromSlowDb(string query)
    {
        return "Hello World!";
    }
}

Давайте скажем, посетитель А ищет. Кеш пуст, блокировка установлена ​​и результат запрашивается из базы данных. Теперь посетитель B выполняет другой поиск: не придется ли посетителю B ждать у замка, пока поиск посетителя A не завершится? Я действительно хотел, чтобы B немедленно вызвал базу данных, потому что результаты будут другими, а база данных может обрабатывать несколько запросов - я просто не хочу повторять дорогостоящие ненужные запросы.

Каков будет правильный подход для этого сценария?

7
задан Jakob Gade 7 April 2011 в 09:16
поделиться