2010-07-22 88 views
3

我有ASHX HTTPHandler實現IRequiresSessionState。當我調用這個處理程序,並在另一個窗口中調用同一應用程序的aspx頁面時,asx頁面不會開始處理,直到ashx頁面完成處理。即使從兩個不同的窗口調用相同的ashx頁面,也會顯示被調用的頁面先執行,然後再執行下一個頁面。HTTPHandler:IRequiresSessionState暫停執行頁面

當我不落實IRequiresSessionState,頁面異步加載,而無需等待其他網頁來完成。

這可能是最終用戶,想在多個窗口的工作誰嚴重的瓶頸。

會話具有用戶特定的數據。如果上述方法不起作用,則需要替代方式來存儲會話的用戶特定數據,這可以在HTTPHandler中使用。

其他信息: - 正在使用ASHX處理程序處理和發送文件,這需要會話內部。

+0

再現行爲,看起來的確嚇人。通用處理程序中的一個簡單的'Thread.Sleep'會殺死所有其他請求。 – 2010-07-22 20:53:32

+1

'IReadOnlySessionState'實際工作。 – 2010-07-22 20:59:27

+0

@Darnin:如前所述,我有ASHX處理程序,所以Thread.Sleep不應該殺死所有請求,並且它不在我的代碼中。 上午正在修改會話數據,所以我需要IRequireSessionState。 另外我更感興趣的是爲什麼會發生這種情況。 – BigBoss 2010-07-22 22:11:52

回答

4

會話狀態訪問要求aspx頁面和處理程序按順序運行。每個頁面/處理程序可以讀取和寫入會話狀態。要處理這個問題,不會在會話狀態中創建任何錯誤.net將一次只運行一個錯誤。 正如達林所說,以只讀會話狀態運行將改善情況。如果需要只讀訪問,Asp.net將允許多個處理程序同時運行。但是,該頁面將需要對會話的寫入權限,因此在aspx頁面本身運行時不會運行處理程序。這是標準的多讀卡器單寫入程序鎖定模式。您可以同時擁有多個閱讀器,但只能有一個作者。

,使這項工作的唯一方法是讓處理器不需要會話狀態,使他們在那T他ASPX頁面運行的同時運行。

您可以通過查找另一種存儲此數據而不是使用會話狀態的方法來解決此問題。您可以實現自己的共享緩存/數據結構,但是您也需要爲該結構提供類似的鎖定(多讀取器/單寫入器)。

+0

所以我相信這會鎖定頁面處理,只處理正在處理正在處理的會話。其他用戶應該能夠在不等待的情況下訪問頁面。這是對的嗎? – BigBoss 2010-07-26 14:16:03

+0

是的。這是一個基於會話的鎖定,並且只會阻止其他使用相同會話的請求。具有不同會話的其他用戶將能夠訪問同一頁面而不會阻塞。 – Mike 2010-07-26 14:21:50

0

除了@Mike關於IRequiresSessionState強制每個「用戶」(會話)一次只處理一個請求的要點之外,還有一個理由需要這個。

假設你有一個Ajax服務(與通用處理器來實現 - * ashx的)執行基於上述發佈數據特定用戶的「更新」。假設更新很重(大約250ms),並且涉及到數據庫的「讀取/合併/寫入」過程(同樣,數據被隔離給個人用戶)。然而,客戶端(應用程序,網站等)可以快速連續地執行服務器無法控制的多個呼叫。

通過實現IRequiresSessionState(簡單地將它包括爲您的泛型處理程序的接口),ASP.NET將確保對給定用戶/會話的進行串行處理。然而,多個用戶仍然可以並行地調用更新。這可以讓我們避免「丟失更新問題」,因爲第二個請求在第一個請求完成更新之前不會檢索數據的副本。

public class SaveDataHandler : IHttpHandler, IRequiresSessionState 
{ 
    public void ProcessRequest(HttpContext context) 
    { 
     // Read request parameters 
     // Read database (user specific data) 
     // Process 
     // Write back to database (user specific data) 
    } 

    public bool IsReusable => false; 
}