zoukankan      html  css  js  c++  java
  • 异常"ViewStateException: The client disconnected"引起的

    跟踪网站日志的时候发现了这个异常,如下是异常的详细信息:

    错误信息:The client disconnected.  2009-4-6 19:35:41 
    at System.Web.UI.ViewStateException.ThrowError(Exception inner, String persistedState, String errorPageMessage, Boolean macValidationError)
    at System.Web.UI.HiddenFieldPageStatePersister.Load()
    at System.Web.UI.Page.LoadPageStateFromPersistenceMedium()
    at SpringStudio.Naming.Website.PageBase.LoadPageStateFromPersistenceMedium()
    at System.Web.UI.Page.LoadAllState()
    at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)



    看看StackTrace就知道,这个错误是由于ViewState引发的。ViewState是个让人即爱又恨的东西。说是爱吧,是因为用起来很方便,控件的状态能自动维持。说是恨吧,原因是其性能不是太高,尤其是页面较大的时候。不知道当初微软在设计.NET的时候为什么的引入ViewState机制,我研究过一些用.NET开发的网站,很多网站都是直接禁用了ViewState。原因很简单,一个稍微大一点的页面,产生的ViewState简直让人受不了,这么大的ViewState将对网络带宽带来极大的压力。同时,对系统性能也会造成一定的影响,因为为了能把数据存储在网页中,系统必须对各种对象做串行化处理,最后编码为Base64的字符串存储在网页中的隐藏字段中(一般默认是存储在名为__VIEWSTATE的隐藏Field中)。当网页被Post到服务器的时候,服务器又将对里面的数据做反串行化处理,在反串行化之前还得验证数据的完整性和正确性。上面这个错误,就是因为在反串行化的过程中,由于客户端浏览器未能完整的Post保存在ViewState中的数据而引发的异常。如果用户所在的网络情况不是很好,Post一个表单需要较长的时间,用户在等待的时候点击了“停止”按钮,或者干脆转向了其他页面,这个时候,客服端单方面中断了网络链接,即所谓的“The client disconnected”,导致回发的ViewState不完整而引发了此异常。一般情况下,这个异常对于服务器和用户体验都不会带来太大的影响,故服务器在捕获到这个异常的时候可以忽略它。

    即便我们可以忽略这个异常,但有几点还是值得注意和思考:

    1. 页面中不需要的ViewState的控件,尽量将其EnableViewState设置为False,这样可以大大降低网页的ViewState。如果你的页面更本不需要使用ViewState,则干脆从页面级,甚至是整个站点级(在Web.config中设置)禁止ViewState,这样就能有效防止该异常的发生,同时提高系统性能。

    2. ViewState从设计上来说是个好东西,但苦于网站的带宽和服务器资源总是有限的,所以在设计网站的时候,就得尽量少用ViewState。等什么时候,我们的网络带宽足够大,并且Server足够Powerful的时候,这个问题就可以忽略了。

    3. 如果非要使用ViewState,有两种方法可以减少ViewState的大小。第一,启用压缩技术。在ViewState被发送到客户端之前,调用压缩算法将其压缩。根据我的经验,就是一般的zip压缩,压缩率也在30-50%之间,有的甚至更高,这取决于具体的数据。当数据回发的时候,先将其做解压缩处理,然后在执行其他的ViewState操作。第二,将ViewState存储在服务器的硬盘上面,道理一样,在发送到客户端之前,将数据以文件的形式保存在服务器的硬盘上。这里需要注意的是文件名必须的唯一,原因就不多说了。当页面回发的时候,直接根据文件名从硬盘上加载ViewState即可。这两种方式的实现都很简单,重写页面的如下两个事件即可:
    1. protected override void SavePageStateToPersistenceMedium(object viewState)
    2. {
    3.     // 压缩ViewState或者存到到硬盘上
    4. }

    5. protected override object LoadPageStateFromPersistenceMedium()
    6. {
    7.     // 解压ViewState或者从硬盘加载数据
    8. }
    复制代码
    上面谈到的两种方法都有其局限性,第一种方法节约了网络带宽,牺牲了CUP计算时间,因为压缩算法还是比较费CPU时间的。第二种方法,极大的节约了网络带宽,但也极大的增加了I/O的负荷。具体用那种方法,只能具体问题具体分析了,不能一概而论。

    4. 如果本身网页的ViewState不是很大,网站却经常抛出这个异常,则至少可以说明你的网站速度太慢了,用户在提交表单的时候需要花费一个较长的等待时间。这种情况,就得考虑为你的网站做带宽和硬件上的升级了。
  • 相关阅读:
    PIE-Basic 频率域滤波
    使用CefSharp前端后台交换
    CefSharp F12打开DevTools查看console js和c#方法互相调用
    js和C#互相调用
    C# 矢量图EMF 总结
    key
    关于IdentityServer4不使用MVC页面进行登录(跨域发送验证请求)的一些问题(前后端分离的验证)
    C#版的省份编码字典
    EFCore显示加载模式下,自动包含导航属性(只包含第一层的导航属性)的方法
    EFCore批量实现全局查询筛选器
  • 原文地址:https://www.cnblogs.com/NoRoad/p/1676437.html
Copyright © 2011-2022 走看看