代码之家  ›  专栏  ›  技术社区  ›  Matt Dawdy

在.ashx处理程序中查看状态?

  •  4
  • Matt Dawdy  · 技术社区  · 15 年前

    我有一个处理程序(例如list.ashx),它有一个方法来检索一个大数据集,然后只获取将显示在任何给定数据“页面”上的记录。我们允许用户对这些结果进行排序。因此,在任何给定的页面运行中,我都将检索几秒钟/分钟前刚获得的数据集,但会对它们重新排序,或显示下一页数据等。

    我的观点是我的数据集没有改变。通常情况下,数据集会被困在页面的viewstate中,但是由于我使用的是一个处理程序,我没有那么方便。至少我不这么认为。

    那么,在使用处理程序时,存储与当前用户给定页面相关联的viewstate的常用方法是什么?是否有方法获取数据集,以某种方式对其进行编码并将其发送回用户,然后在下一次调用时,将其传回,然后从这些位重新水化数据集?

    我不认为session是存储它的好地方,因为我们可能有1000个用户都在查看不同数据集的不同数据,这可能会让服务器崩溃。至少我是这么认为的。

    有人对这种情况有经验吗?你能给我一些建议吗?

    3 回复  |  直到 15 年前
        1
  •  3
  •   Kelsey    15 年前

    在这种情况下,我将使用一个缓存,其中包含某种类型的用户和查询信息作为键。原因是你说它是一个大数据集。对了,有些事你不想不断地上下推。记住,如果数据处于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 只是用一些缓存来交换带宽和处理大量的请求。在我看来,你越少来回传送越好。

        2
  •  2
  •   Oleks    15 年前

    为什么不实现服务器端缓存?

    我知道,您正在检索大量数据,然后只将此数据中的必要记录返回给不同的客户端。所以你可以用 HttpContext.Current.Cache 这个的属性。

    例如,可以使用封装数据检索逻辑的属性(第一次请求时从原始数据存储中获取,然后放入缓存,下一次请求时从缓存获取)。在这种情况下,所有必要的数据操作(分页等)都可以比每次请求检索大量数据快得多。

    当客户机具有不同的数据源(意味着每个客户机都有自己的数据源)时,也可以实现上述解决方案。我认为每个客户机至少有一个标识符,因此您可以为不同的客户机使用不同的缓存(客户机标识符作为缓存密钥的一部分)。

        3
  •  1
  •   cortijon    15 年前

    最好的方法是通过在ashx处理程序的请求主体中包含序列化数据集来“增长自己的数据”。然后,您的处理程序将通过检查来查看请求是否确实具有主体 Request.ContentLength 然后从 Request.InputStream ,如果它确实将该主体序列化回数据集中,而不是从数据库中读取。