提高ASP.net性能的十种方法

一、返回多个数据集

  检查你的访问数据库的代码,看是否存在着要返回多次的请求。每次往返降低了你的应用程序的每秒能够响应请求的次数。通过在单个数据库请求中返回多个结果集,可以减少与数据库通信的时间,使你的系统具有扩展性,也可以减少数据库服务器响应请求的工作量。

  如果用动态的SQL语句来返回多个数据集,那用存储过程来替代动态的SQL语句会更好些。是否把业务逻辑写到存储过程中,这个有点争议。但是我认为,把业务逻辑写到存储过程里面可以限制返回结果集的大小,减小网络数据的流量,在逻辑层也不用在过滤数据,这是一个好事情。

  用SqlCommand对象的ExecuteReader方法返回一个强类型的业务对象,再调用NextResult方法来移动数据集指针来定位数据集。返回多个ArrayList强类型对象。只从数据库中返回你需要的数据可以大大的减小你的服务器所耗用的内存。

二、对数据进行分页

  ASP.NETDataGrid有一个非常有用的功能:分页。如果DataGrid允许分页,在某一时刻它只下载某一页的数据,另外,它有一个数据分页的济览导航栏,它让你可以选择浏览某一页,而且每次只下载一页的数据。

  但是它有一个小小的缺点,就是你必须把所有的数据都绑定到DataGrid中。也就是说,你的数据层必须返回所有的数据,然后DataGrid再根据当前页过滤出当前页所需要的数据显示出来。如果有一个一万条记录的结果集要用DataGrid进行分页,假设DataGrid每页只显示25条数据,那就意味着每次请求都有9975条数据都是要丢弃的。每次请求都要返回这么大的数据集,对应用程序的性能影响是非常大的。

  一个好的解决方案是写一个分页的存储过程,例如对Northwind数据库orders表的分页存储过程。你只需要传当前页码,每页显示的条数两个参数进来,存储过程会返回相应的结果。

  在服务器端,我专门写了一个分页的控件来处理数据的分页,在这里,我用了第一个方法,在一个存储过程里面返回了两个结果集:数据记录总数和要求的结果集。

  返回的记录总数取决于要执行查询,例如,一个where条件可以限制返回的结果集的大小。因为在分页界面中必须要根据数据集记录的大小来计算总的页数,所以必须要返回结果集的记录数。例如,如果一共有1000000条记录,如果用where条件就可以过滤成只返回1000条记录,存储过程的分页逻辑应该知道返回那些需要显示的数据。

三、连接池

  用TCP来连接你的应用程序与数据库是一件昂贵的事情(很费时的事情),微软的开发者可以通过用连接池来反复的使用数据库的连接。比起每次请求都用TCP来连一次数据库,连接池只有在不存在有效的连接时才新建一个TCP连接。当关闭一个连接的时候,它会被放到池中,它仍然会保持与数据库的连接,这样就可以减少与数据库的TCP连接次数。

  当然,你要注意那些忘记关的连接,你应在每次用完连接后马上关闭它。我要强调的是:无论什么人说.net framework中的GC(垃圾收集器)总会在你用完连接对象后调用连接对象的Close或者Dispose方法显式的关闭你的连接。不要期望CLR会在你想象的时间内关掉连接,虽然CLR最终都要销毁对象和关闭边接,但是我们并不能确定它到底会在什么时候做这些事情。  

  要用连接池优化,有两条规则,第一,打开连接,处理数据,然后关闭连接。如果你必须在每次请求中多次打开或关闭连接,这好过一直打开一个边接,然后把它传到各个方法中。第二,用相同的连接字符串(或者用相同的用户标识,当你用集成认证的时候)。如果你没有用相同的连接字符串,如你用基于登录用户的连接字符串,这将不能利用连接池的优化功能。如果你用的是集成的论证,因为用户很多,所以你也不能充分利用连接池的优化功能。.NET CLR提供了一个数据性能计数器,它在我们需要跟踪程序性能特性的时候非常有用,当然也包括连接池的跟踪了。     

  无论你的应用程序什么时候要连在另一台机子的资源,如数据库,你都应该重点优化你连资源所花的时间,接收和发送数据的时间,以及往返回之间的次数。优化你的应用程序中的每一个处理点(process hop),它是提高你的应用的性能的出发点。  

  应用程序层包含与数据层连接,传送数据到相应的类的实例以及业务处理的逻辑。例如,在Community Server中,要组装一个Forums或者Threads集合,然后应用业务逻辑,如授权,更重要的,这里要完成缓存逻辑。

四、ASP.NET缓存API

   在写应用程序之前,你要做的第一件事是让应用程序最大化的利用ASP.NET的缓存功能。

  如果你的组件是要在Asp.net应用程序中运行,你只要把System.Web.dll引用到你的项目中就可以了。然后用HttpRuntime.Cache属性就可访问Cache了(也可以通过Page.CacheHttpContext.Cache访问)。  

  有以下几条缓存数据的规则。第一,数据可能会被频繁的被使用,这种数据可以缓存。第二,数据的访问频率非常高,或者一个数据的访问频率不高,但是它的生存周期很长,这样的数据最好也缓存起来。第三是一个常常被忽略的问题,有时候我们缓存了太多数据,通常在一台X86的机子上,如果你要缓存的数据超过800M的话,就会出现内存溢出的错误。所以说缓存是有限的。换名话说,你应该估计缓存集的大小,把缓存集的大小限制在10以内,否则它可能会出问题。在Asp.net中,如果缓存过大的话也会报内存溢出错误,特别是如果缓存大的DataSet对象的时候。

这里有几个你必须了解的重要的缓存机制。首先是缓存实现了“最近使用”原则( a least-recently-used algorithm),当缓存少的时候,它会自动的强制清除那些无用的缓存。其次 “条件依赖”强制清除原则(expiration dependencies),条件可以是时间,关键字和文件。以时间作为条件是最常用的。在asp.net2.0中增加一更强的条件,就是数据库条件。当数据库中的数据发生变化时,就会强制清除缓存  

五、预请求缓存

  在前面,我们只对某些地方作了一个小小的性能改进也可以获得大的性能提升,用预请求缓存来提升程序的性能是很不错的。

  虽然Cache API设计成用来保存某段时间的数据,而预请求缓存只是保存某个时期的某个请求的内容。如果某个请求的访问频率高,而且这个请求只需要提取,应用,修改或者更新数据一次。那么就可以预缓存该请求。我们举个例子来说明。

  在BS的论坛应用程序中,每一个页面的服务器控件都要求得到用于决定它的皮肤(skin)的自定义的数据,以决定用哪个样式表及其它的一些个性化的东西。这里面的某些数据可能要长时间的保存,有些时间则不然,如控件的skin数据,它只需要应用一次,而后就可以一直使用。

  要实现预请求缓存,用Asp.net HttpContext类,HttpContext类的实例在每一个请求中创建,在请求期间的任何地方都可以通过HttpContext.Current属性访问。HttpContext类有一个Items集合属性,在请求期间所有的对象和数据都被添加到这个集合中缓存起来。和你用Cache缓存访问频率高数据一样,你可以用HttpContext.Items缓存那些每个请求都要用到的基础数据。它背后的逻辑很简单:我们向HttpContext.Items中添加一个数据,然后再从它里面读出数据。

六、后台处理

  通过上面的方法你的应用程序应该运行得很快了,是不是?但是在某些时候,程序中的一次请求中可能要执行一个非常耗时的任务。如发送邮件或者是检查提交的数据的正确性等。

  当我们把asp.net Forums 1.0集成在CS中的时侯,发现提交一个新的帖子的时候会非常的慢。每次新增一个帖子的时侯,应用程序首先要检查这个帖子是不是重复提的,然后用“badword”过滤器来过滤,检查图片附加码,作帖子的索引,把它添加到合适的队列中,验证它的附件,最后,发邮件到它的订阅者邮件箱中。显然,这个工作量很大。

  结果是它把大量的时间都花在做索引和发送邮件中了。做帖子的索引是一项很耗时的操作,而发邮件给订阅都需要连接到SMTP服务,然后给每一个订阅者都发一封邮件,随着订阅用户的增加,发送邮件的时间会更长。

  索引和发邮件并不需要在每次请求时触发,理想状态下,我们想要批量的处理这些操作,每次只发25封邮件或者每隔5分钟把所有的要发的新邮件发一次。我们决定使用与数据库原型缓存一样的代码,但是失败了,所以又不得不回到VS.NET 2005

  我们在System.Threading命名空间下找到了Timer类,这个类非常有用,但却很少有人知道,Web开发人员则更少有人知道了。一旦他建了该类的实例,每隔一个指定的时间,Timer类就会从线程池中的一个线程中调用指定的回调函数。这意味着你的asp.net应用程序可以在没有请求的时候也可以运行。这就是后以处理的解决方案。你就可以让做索引和发邮件工作在后台运行,而不是在每次请求的时候必须执行。

  后台运行的技术有两个问题,第一是,当你的应用程序域卸载后,Timer类实例就会停止运行了。也就是不会调用回调方法了。另外,因为CLR的每个进程中都有许多的线程在运行,你将很难让Timer获得一个线程来执行它,或者能执行它,但会延时。Asp.net层要尽量少的使用这种技术,以减少进程中线程的数量,或者只让请求用一小部分的线程。当然如果你有大量的异步工作的话,那就只能用它了。

七、页面输出缓存和代理服务

  Asp.net是你的界面层(或者说应该是),它包含页面,用户控件,服务器控件(HttpHandlers HttpModules)以及它们生成的内容。如果你有一个Asp.net页面用来输出htmlxml,imgae或者是其它的数据,对每一个请求你都用代码来生成相同的输出内容,你就很有必要考虑用页面输出缓存了。

只要简单的把下面的这一行代码复制到你的页面中就可以实现了:

<%@ PageOutputCache VaryByParams=none Duration=60 %>

就可以有效的利用第一次请求里生成的页面输出缓存内容,60秒后重新生成一道页面内容。这种技术其实也是运用一些低层的Cache API来实现。用页面输出缓存有几个参数可以配置,如上面所说的VaryByParams参数,该参数表示什么时候触发重输出的条件,也可以指定在Http GetHttp Post 请求模式下缓存输出。例如当我们设置该参数为VaryByParams=Report”的时候,default.aspx?Report=1或者default.aspx?Report=2请求的输出都会被缓存起来。参数的值可以是多个用分号隔开参数。

  许多人都没有意识到当用页面输出缓存的时候,asp.net也会生成HTTP头集(HTTP Header)保存在下游的缓存服务器中,这些信息可以用于Microsoft Internet安全性中以及加速服务器的响应速度。当HTTP缓存的头被重置时,请求的内容会被缓在网络资源中,当客户端再次请求该内容时,就不会再从源服务器上获得内容了,而直接从缓存中获得内容。

  虽然用页面输出缓存不提高你的应用程序性能,但是它能减少了从的服务器中加载已缓存页面内容的次数。当然,这仅限于缓存匿名用户可以访问的页面。因为一旦页面被缓存后,就不能再执行授权操作了。

八、 IIS6.0Kernel Caching

  如果你的应用程序没用运行在IIS6.0(windows server 2003)中,那么你就失去了一些很好的提高应用程序性能的方法。在第七个方法中,我讲了用页面输出缓存提高应用程序的性能的方法。在IIS5.0中,当一个请求到来到IIS后,IIS会把它转给asp.net,当应用了页面输出缓存时,ASP.NET中的HttpHandler会接到该请求,HttpHandler从缓存中把内容取出来并返回。

  如果你用的是IIS6.0,它有一个非常好的功能就是Kernel Caching,而且你不必修改asp.net程序中任何代码。当asp.net接到一个已缓存的请求,IISKernel Cache会从缓存中得到它的一份拷贝。当从网络中传来一个请求的时,Kernel层会得到该请求,如果该请求被缓存起来了,就直接把缓存的数据返回,这样就完工了。这就意味着当你用IISKernel Caching来缓存页面输出时,你将获得不可置信的性能提升。在开发VS.NET 2005 asp.net时有一点,我是专门负asp.net性能的程序经理,我的程序员用了这个方法,我看了所有日报表数据,发现用kernel model caching的结果总是最快的。它们的一个共同的特征就是网络的请求和响应量很大,IIS只占用了5%CPU资源。这是令人惊奇的。有许多让你使用用IIS6.0的理由,但kernel cashing是最好的一个。

九、 Gzip压缩数据

  除非你的CPU占用率太高了,才有必要用提升服务器性能的技巧。用gzip压缩数据的方法可以减少你发送到服务端的数据量,也可以提高页面的运行速度,同时也减少了网络的流量。怎么样更好的压缩数据取决于你要发送的数据,还有就是客户端的浏览器支不支持(IIS把用gzip压缩后的数据发送到客户端,客户端要支持gzip才能解析,IE6.0Firefox都支持)。这样你的服务器每秒能多响应一些请求,同样,你也减少了发送响应的数据量,也就能多发送一些请求了。

  好消息,gzip压缩已经被集成在IIS6.0中了,它比IIS5.0gzip更好。不幸的是,在IIS6.0中启用gzip压缩,你不能在IIS6.0的属性对话中设置。IIS开发团队把gzip压缩功能开发出来了,但他们却忘了在管理员窗口中让管理员能很方便的启用它。要启用gzip压缩,你只能深入IIS6.0xml配置文件中修改它的配置。

  除了阅读本文以外看看Brad Wilson写的 IIS6 压缩一文:http://www.dotnetdevs.com/articles/IIS6compression.aspx;另外还有一篇介绍aspx压缩基础知识的文章,Enable ASPX Compression in IIS。但是要注意,在IIS6中动态压缩和kernel cashing是互斥的。

十、 服务器控件的ViewState

  ViewStateasp.net中的一个特性,它用于把生成页面要用的一状态值保存在一个隐藏域中。当页面被回传到服务器时,服务器要解析,校验和应用ViewState中的数据以还原页面的控件树。ViewState是一个非常有用的特性,它能持久化客户端的状态而不用cookie或者服务器的内存。大部分的服务器控件都是用ViewState来持久化那些在页面中与用户交互的元素的状态值。例如,用以保存用于分页的当前页的页码。

  用ViewState会带来一些负面的影响。首先,它加大的服务器的响应和请求的时间。其次,每次回传时都增加了序列化和反序列化数据的时间。最后,它还消耗了服务器更多的内存。

  许多的服务器控件很趋于使用ViewState,如DataGrid,而有时候是没有必须使用的。默认情况下是允许使用ViewState的,如果你不想使用ViewState的话,你可以在控件或页面级别把关闭它。在控件中,你只要把EnableViewState属性设为False就可以了;你也可以在页面中设置,使它的范围扩展到整个页面中: <%@ Page EnableViewState=false %> 如果页面无需回传或者每次请求页面只是呈现控件。你就应该在页面级别中把ViewState关掉。

转载于:https://www.cnblogs.com/dingjie08/archive/2009/07/22/1528336.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/262409.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java mysql failover_mysqlfailover测试

mysqlfailover是mysql官方用python语言写的一款工具&#xff0c;包含在mysql utilities工具集中。主要作用是保障mysql高可用。他会定时检测节点状态&#xff0c;当master节点不可用时&#xff0c;会自动转移到从节点上&#xff0c;同时剩余的从节点都会指向转以后的节点。如何…

RGB/YUV/YCbCr--关于显示,颜色你需要了解的一些事

工作中常听说RGB/YUV/YCbCr 这样一些名词&#xff0c;概念上似乎很混淆&#xff1f;这里是一个简介&#xff0c;部分内容来自wiki&#xff0c;理解不对的地方欢迎指正。 A&#xff1a;首先两个基本概念&#xff1a; Color model和Color Space. 1. Color Model: 为了表达人眼观察…

C# winfrom listView

转自http://hi.baidu.com/gaoisbest/item/84034943d4d94195823ae12b 1.如何为listview手动添加第一列和第二列数据 for (int i 0; i < 10; i) { ListViewItem Item new ListViewItem(); Item.Text dt.Rows[i][1].ToString();//读取数据库中字段 Item.Tag dt.…

淘宝评价网----类反淘宝联盟上线

反淘宝联盟&#xff0c;淘宝该反吗&#xff1f; 淘宝该反对吗&#xff1f; 其实淘宝已经做的很好了 我们反对的只是商家的不诚信的行为&#xff0c;但是在淘宝上我们又得不到对商家的全面的全面了解&#xff0c;所以我们反了&#xff1b;反&#xff0c;只是途径&#xff0c;不是…

Python从键盘输入多行文本数据的方法

Python中的Input()函数在输入时&#xff0c;遇到回车符&#xff0c;那么一次输入就结束了。这不能满足输入多行文本并且行数也不确定的情形&#xff0c;当然输入空行也是允许的。 方法1&#xff1a;直接利用input()函数逐行读取数据&#xff0c;直到EOF。利用异常处理机制实现…

[教程指导]索尼官方4.0.3系统一键root方法! [复制链接]

[教程指导]索尼官方4.0.3系统一键root方法&#xff01; [复制链接] 青青子衿198976青青子衿198976注册时间2011-9-26最后登录2012-9-15在线时间730 小时阅读权限150积分3996帖子1173精华32UID13306151版主 在线时间730 小时经验1629 分贡献2693 点极币10442 极币最后登录2012-9…

creator图片循环显示_CocosCreator背景图循环播放

以前在玩小游戏的时候发现有的小游戏背景图一直再动&#xff0c;视觉效果挺好&#xff0c;给人一种炫炫的感觉&#xff0c;让我这写后台的码农很是羡慕和膜拜。没想到天意弄人&#xff0c;我也开始写游戏前端了刚接触CocosCreator,好多东西都不懂&#xff0c;整个懵逼状态&…

完全卸载oracle11g步骤

1、 开始&#xff0d;&#xff1e;设置&#xff0d;&#xff1e;控制面板&#xff0d;&#xff1e;管理工具&#xff0d;&#xff1e;服务 停止所有Oracle服务。2、 开始&#xff0d;&#xff1e;程序&#xff0d;&#xff1e;Oracle - OraHome81&#xff0d;&#xff1e;Oracl…

PyCharm安装开发游戏的Pygame

方式一&#xff1a;利用PyCharm导入Pygame包 通常情况下&#xff0c;Pygame可以通过Pycharm的单击菜单File-->Settings...&#xff0c;弹出Settings窗口&#xff0c;在左侧栏中选择Project ***&#xff08;此处***是你的当前项目名&#xff09;-->Project Interpreter&a…

Jsp-Servlet 概要总结[转]

Servlet三个要素: 1.必须继承自HttpServlet 2.必须实现doGet()或者doPost() 3.必须在web.xml中配置Servlet <servlet> <servlet-name> </servlet-name> <servlet-class> </servlet-class> </servlet><servlet-mapping> <servlet-…

php函数学习二

rename():修改文件的名字 addcslashes(&#xff09;&#xff1a;过滤用户提交的敏感字符&#xff0c;一般通过转义提高安全性 dechex():把十进制数据转化为十六进制数据 Abs: 取得绝对值。 Acos: 取得反余弦值。 ada_afetch: 取得资料库的传回列。 ada_autocommit: 开关自动更…

sybase数据库导出mysql_使用BCP从Sybase远程数据库中导出数据

1.在本机安装Sybase ASE 15&#xff0c;我装的开发版全套&#xff0c;懒得去仔细看需要哪个了2.在Sybase安装目录里找到ini\sql.ini&#xff0c;在里面添加数据源例如&#xff1a;[MYDS]masterNLWNSCK,192.168.1.201,5000queryNLWNSCK,192.168.1.201,5000其中MYDS是数据源名称&…

Web项目,要求:保存用户名和密码在Cookie中,下次登录不再重新输入

设计一个实现登录功能的Web项目&#xff0c;要求&#xff1a;保存用户名和密码在Cookie中&#xff0c;下次登录不再重新输入 var cookie {};//设置 cookie.SetCookiesfunction(name,value,exptime){ try{ if(arguments.length 2) return arguments.callee(…

Pycharm使用black作为Python代码格式化外部工具

Pycharm菜单Code->Reformat Code能对Python代码进行格式化&#xff0c;但是black能进一步规范格式&#xff0c;它是PEP8的严格子集。 本次操作的相关环境信息如下&#xff1a;Pycharm 2018版&#xff0c;Python3.6,&#xff08;注意&#xff0c;写本文时的black只支持在Pyt…

WCF的学习资源

这一两天开始学习WCF&#xff0c;两天前我对WCF一无所知&#xff0c;现在也所知甚少&#xff0c;不过倒是在网上找到了一些学习WCF的不错的资源&#xff0c;在这里收录整理如下&#xff1a;1、http://www.cnblogs.com/jillzhang/tag/WCF/博主张玉彬&#xff0c;其对分布式应用程…

python --函数

转http://www.cnblogs.com/vamei/archive/2012/06/01/2529500.html 函数最重要的目的是方便我们重复使用相同的一段程序。 将一些操作隶属于一个函数&#xff0c;以后你想实现相同的操作的时候&#xff0c;只用调用函数名就可以&#xff0c;而不需要重复敲所有的语句。 函数的定…

mysql slave 线程 简书_【MySQL】你真的读懂了slave status吗?

前言:大家平时在检查主从复制的时候基本上都会使用 show slave status来看主从复制的情况&#xff0c;那么你真的读懂每个指标项了吗&#xff1f;一、status指标解读rootlocalhost [(none)]>show slave status\GERROR 2006 (HY000): MySQL server has gone awayNo connectio…

Python中用input()和print()体现输入输出重定向

众所周知&#xff0c;在Python中&#xff0c; 语句&#xff1a;变量input() 的功能是&#xff1a;从键盘读取数据到内存变量&#xff0c;此过程为输入。此时&#xff0c;键盘为标准输入设备&#xff0c;对应的文件对象名为sys.stdin。 语句&#xff1a;input(变量) 的功能是&…

【DI专题】在 DI 脚本文件中调用存储过程

以前用过&#xff0c;但是隔很久不用&#xff0c;还是会有点忘记&#xff0c;还是记下来吧&#xff1a;&#xff09; 1.在左侧datastore区域&#xff0c;选择数据库&#xff0c;选择 Function,单击右键&#xff0c;选择 import by name; 2.在弹出对话框中&#xff0c;输入待导入…

国外网站设计欣赏:30个优秀的国外咖啡网站设计

梦想天空博客向大家分享各种类型的优秀网站作品&#xff0c;有电子商务网站设计、旅游网站设计、餐馆网站设计、设计工作室网站设计、大学网站设计以及各种色系&#xff0c;各种风格的网站设计作品。今天这篇文章给大家带来30个优秀的国外咖啡网站设计作品&#xff0c;一起欣赏…