2010-07-22 84 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; 
}