2010-05-04 49 views
2

除了阻止其他線程讀取緩存之外,還有什麼其他問題在鎖定面向公衆的網站的緩存插入方法時應該考慮哪些問題?如果我鎖定HttpContext.Current.Cache.Insert方法

實際的數據檢索和插入緩存應該不超過1秒,我們可以忍受。更重要的是,我不希望多個線程可能同時觸發Insert方法。

的示例代碼如下所示:

public static readonly object _syncRoot = new object(); 

if (HttpContext.Current.Cache["key"] == null) 
{ 
    lock (_syncRoot) 
    { 
    HttpContext.Current.Cache.Insert("key", "DATA", null, DateTime.Now.AddMinutes(5), Cache.NoSlidingExpiration, CacheItemPriority.Normal, null); 
    } 
} 

    Response.Write(HttpContext.Current.Cache["key"]); 

回答

2

我希望你這樣做是爲了防止數據檢索超過一次,也許是因爲數據量很高,這可能對影響你的服務器時,多個用戶觸發該檢索。

像這樣的鎖只是在Cache.Insert本身是沒用的,因爲這種方法是線程安全的。像這樣的鎖可以防止雙數據檢索有用的,但在這種情況下,你應該考慮使用雙重檢查鎖定:

var data = HttpContext.Current.Cache["key"]; 
if (data == null) 
{ 
    lock (_syncRoot) 
    { 
    // Here, check again for null after the lock. 
    var data = HttpContext.Current.Cache["key"]; 
    if (data == null) 
    { 
     var data = [RETRIEVE DATA] 
     HttpContext.Current.Cache.Insert("key", data, null, ...); 
    } 
} 
return data; 

但你的主要問題。除了鎖定時間過長的風險,導致您的Web應用程序出現大的延遲,沒有什麼可擔心的:-)。圍繞着Cache.Insert本身鎖定,你會沒有傷害。

+0

謝謝,但我不確定我瞭解雙重檢查鎖的部分。第二個空檢查帶來的好處是什麼? – Ekk 2010-05-04 08:58:41

+0

這第二個'data == null'檢查確保'[RETRIEVE DATA]'部分只執行一次。當多個線程同時調用該方法時,'lock(_syncRoot)'確保一次只有一個線程執行該代碼塊。所有其他線程都必須等待。但是當第一個線程完成時,第一個等待線程將執行該代碼並執行'[RETRIEVE DATA]'部分。這就是爲什麼第二個'data == null'檢查。 – Steven 2010-05-04 10:43:20