2010-04-27 70 views
4

我有一個處理程序(例如list.ashx),它擁有一個檢索大型數據集的方法,然後只抓取將在任何給定的「頁面」數據上顯示的記錄。我們允許用戶對這些結果進行排序。因此,在任何給定的頁面上,我將檢索剛纔幾秒/分鐘前的數據集,但重新排序它們或顯示下一頁數據等。在.ashx處理程序中的Viewstate?

我的觀點是我的數據集真的沒有改變。通常情況下,數據集會陷入頁面的視圖狀態,但由於我使用的是處理程序,因此我沒有那麼方便。至少我不這麼認爲。

那麼,在使用處理程序時,存儲與當前用戶給定頁面關聯的視圖狀態的常用方法是什麼?有沒有辦法獲取數據集,以某種方式對其進行編碼並將其發回給用戶,然後在下次調用時將其傳回,然後從這些位中重新組合水平數據集?

我不認爲Session會是一個存儲它的好地方,因爲我們可能有1000個用戶都在查看不同數據的不同數據集,這可能會使服務器癱瘓。至少我是這麼認爲的。

有沒有人有這種情況的任何經驗,你能給我任何建議嗎?

回答

3

在這種情況下,我會使用某種類型的用戶和查詢信息作爲關鍵字的緩存。原因是你說它是一個大型數據集。正確的是,你不希望不斷地在管道中上下推動。請記住,如果服務器位於ViewState並處理它,它仍然必須接收數據。我會做這樣的事情這將其緩存爲特定用戶,有一個短的過期:

public DataSet GetSomeData(string user, string query, string sort) 
{ 
    // You could make the key just based on the query params but figured 
    // you would want the user in there as well. 
    // You could user just the user if you want to limit it to one cached item 
    // per user too. 
    string key = string.Format("{0}:{1}", user, query); 

    DataSet ds = HttpContext.Current.Cache[key] as DataSet; 
    if (ds == null) 
    { 
     // Need to reload or get the data 
     ds = LoadMyData(query); 

     // Now store it and make the expiry short so it doesn't bog up your server 
     // needlessly... worst case you have to retrieve it again because the data 
     // has expired. 
     HttpContext.Current.Cache.Insert(key, ds, null, 
      DateTime.UtcNow.AddMinutes(yourTimeout), 
      System.Web.Caching.Cache.NoSlidingExpiration); 
    } 

    // Perform the sort or leave as default sorting and return 
    return (string.IsNullOrEmpty(sort) ? ds : sortSortMyDataSet(ds, sort)); 
} 

當你說用戶的1000年代,這是否意味着併發用戶?如果您的到期時間爲1分鐘,併發用戶數量將在一分鐘內發出並需要分類。我認爲將數據卸載到像ViewState類似的東西只是交易一些高速緩衝存儲器來處理帶寬和來回處理大量請求的負載。我認爲越少越好。

+0

現在,可能只有100個併發用戶。在接下來的幾個月裏我們會達到1000。我喜歡緩存超時的想法。 有沒有辦法確定IIS是否按時釋放緩存?我的意思是,IIS中是否有一些設置需要激活才能使緩存超時?我不想使用此代碼,然後找出IIS忽略超時。我想測試1分鐘,檢查空值會發現。 感謝您的答案 - 這正是我需要的妥協類型。 – 2010-04-27 17:46:52

1

通過在ASHX處理程序的請求正文中包含序列化的數據集,您可以做的最好的工作是「發展自己」。然後,您的處理程序將通過檢查Request.ContentLength然後從Request.InputStream進行讀取,並且如果它將該主體序列化回數據集而不是從數據庫中讀取,來檢查請求是否確實具有主體。

2

爲什麼不實現服務器端緩存?

據我所知,您正在檢索大量數據,然後僅將此數據中的必要記錄返回給不同的客戶端。所以你可以使用HttpContext.Current.Cache屬性。

E.g.可以使用封裝數據檢索邏輯的屬性(從第一個請求的原始數據存儲獲取,然後放入緩存並從每個下一個請求的緩存中獲取)。在這種情況下,所有必要的數據操作(分頁等)可能比用每個請求檢索大量數據要快得多。

在客戶端具有不同數據源(意味着每個客戶端都有自己的數據源)的情況下,上述解決方案也可以實施。我想每個客戶端都至少有一個標識符,所以你可以爲不同的客戶端使用不同的緩存(客戶端標識符作爲緩存鍵的一部分)。

+0

謝謝你的答案,亞歷克斯。這是Kelsey發佈的很好的描述。我選擇凱爾西作爲公認的答案,僅僅是因爲他們也提供了一個很好的代碼示例。不過,我真的很感謝多方面的確認。 – 2010-04-27 17:55:04