2010-08-26 77 views
3

我有一个Web应用程序,它使用Web服务。主页面运行搜索 - 将参数传递给特定的Web服务方法,然后将结果绑定到gridview。非常大的视图状态打破网络应用程序

我已经在网格上实现了排序和分页。通过将网格绑定的数据表放入视图状态,然后根据需要对其进行读取/排序/过滤,然后重新绑定到网格。

随着从Web服务返回的数据量急剧增加,当我尝试进行页面/排序等时,我收到以下错误。

连接被重置

,而该页面被加载到服务器连接被重置。

我已经搜索了一下,看起来这是一个非常大的视图状态。 但可以肯定的唯一的其他选择是

  1. 限制结果
  2. 棒会话,而不是视图状态
  3. 别的东西,我不知道的数据表

以前我也有在会话中的数据表,因为这些数据需要在页面之间持续存在 - (不会发布,所以viewstate不是一个选项)。随着数据量的增加以及持久化的必要性被删除,我使用viewstate来代替。由于会话需要保存的数据量和使用该应用的用户数量,认为这是比会话更好的选择。

看来可能不是。

我认为,当视图状态变得很大时,那个.net会将它分成多个隐藏的视图状态字段,但看起来我只能看到一个巨大的视图状态,在源代码中查看时遇到问题。

任何人都可以启发我如何避免我得到的错误?如果确实与视图状态中的数据量有关?

回答

1

这听起来像你缓存所有页面的整个数据集,即使你只是呈现一页数据。我会将您的分页更改为仅需要用户所在当前页面的数据。

如果查询很重,并且您不希望经常反复调用它,因为有很多来回分页(您应该测试典型的用法模式),那么我会实现某种类型的在Web服务端缓存逐页缓存(如果数据特定于用户,则由特定用户缓存),并使其过期相当快(例如少数minuites)。

我认为你需要限制你处理的数据总量。将代码更改为不传回可能不需要的额外数据是开始的好地方。

编辑:根据您的意见:

  1. 您不能更改Web服务
  2. 用户可以通过筛选或排序操作查询
  3. 有一个大的数据量由网络服务返回
  4. 该数据是用户特定的

那么我认为你有一个完美的案例可以使用Session。这可能会使用大量用户和数据对服务器征税,因此您可能需要执行一些逻辑来清除Session中的数据,而不是等待它过期(例如,在某些着陆页上,您知道用户在他们完成后,清除会话数据)。

你真的想从ViewState中得到它,因为它是一个巨大的带宽生猪。只要看看你的物理页面大小,数据就会在每一个动作中来回传递。将它移动到Session将消除该带宽使用,并允许您执行所需的一切。

您也可以查看Web服务正在带回的数据,并将其存储在自定义对象中,尽可能使其成为“精简”。如果您在Session中存储DataSetDataTable,那么这些对象可能会有一些额外的开销,您可能不需要将这些数据存储为一些自定义瘦对象的数组,然后绑定到该对象。您需要将WS的结果映射到您的自定义对象,但这是减少内存使用率的一个很好的选择。

让我知道是否有其他东西我缺少。

+0

嗨,感谢您的回复 当然,为了做到这一点,WS将不得不接受排序/页面参数..基本上处理在WS端的分页/排序,并且一次请求一个分页的东西。 但是为了做到这一点,您必须像对每个登录的用户说一样进行独特的主搜索(我们确实有一个会话标识符与每个WS请求一起传递),并按照您的方式进行排序和分页。这是永远不会悲伤发生的。 WS几乎成了一块石头。所以必须与我做什么...继续在下一个评论 – nat 2010-08-26 16:14:14

+0

继续.. 客户端需要所有的数据回来,以便他们可以找到他们想要的懒惰 - 即不做一个非常有针对性的搜索..并筛选网格,以找到他们想要的东西.. 有一个限制参数传递给最初的大型搜索,但设置太低可能使它无法找到他们正在寻找的记录..因为它可能不会返回在从WS 记录集任何其他的想法? – nat 2010-08-26 16:14:50

+0

再次感谢, 您的观点是现货,我已转回​​到会议,一切都很好。 只是以前被视为状态使用会话pooed .. 当然,我认为viewstate是好的,好像他们离开他们的搜索页面坐在那里他们可以回来在2小时,仍然过滤/排序它(如果视图状态不是太大c) 会话(如果我不想让服务器停下来)将会在很短的2小时内掉线。 再次感谢 nat – nat 2010-08-26 16:32:39

1

我不会把数据放在视图状态或会话中。而是存储最低限度的信息以重新从Web服务请求数据集并存储该数据集(在视图状态或会话中,甚至在URL上)。然后使用该数据调用Web服务并对每个请求中的数据作出反应。如有必要,请使用某种形式的缓存(memCache)来提高性能。