2010-04-27 72 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