惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

L
LangChain Blog
V
V2EX
爱范儿
爱范儿
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Martin Fowler
Martin Fowler
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Apple Machine Learning Research
Apple Machine Learning Research
WordPress大学
WordPress大学
有赞技术团队
有赞技术团队
宝玉的分享
宝玉的分享
Last Week in AI
Last Week in AI
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
罗磊的独立博客
小众软件
小众软件
Vercel News
Vercel News
博客园 - 司徒正美
阮一峰的网络日志
阮一峰的网络日志
V
Visual Studio Blog
J
Java Code Geeks
P
Proofpoint News Feed
MongoDB | Blog
MongoDB | Blog
B
Blog
美团技术团队
量子位

博客园 - Ray Wu

推荐纯真(CZ88.NET)IP库 10亿记录的分区讨论,高手进 测试问卷星问卷公开的问题 asp.net高性能之路:无缝切换HttpRuntime.Cache与Memcached,附代码 非常怪异的服务器网络问题【续】,附排查问题思路 非常怪异的服务器网络问题,请有经验的朋友帮忙看下 测试 也谈谈人人网的不正当竞争 腾讯被打残吧,360去死吧 测试 MBTI职业性格测试 很酷的问卷 自动将脚本放在页面底部 Asp.net页面静态内容自动从不同域名加载--极大提升客户端加载速度 使用闭包优雅的为setInterval(setTimeout)传递参数 我的网站PR升了没有? QQ邮箱:要把Bug当宝贝到什么时候? 超轻量级的javascript 评分控件 在线问卷调查平台的创业体会
使用异步页面,后台线程提高用户体验和服务器端性能
Ray Wu · 2008-12-01 · via 博客园 - Ray Wu

     在ASP.net的WEB开发中经常会碰到这样的一个问题:用户操作响应慢的问题。

     出现这种情况的原因可能是本身用户操作就是一个耗时的操作,如发送大批量邮件,插入上万条记录,处理大的上传文件等等。

     根据应用场景的不同,存在不同的解决方案:

    1. 应用场景一

        我曾经碰到这样一个应用: 用户上传一个很大的电子邮件通讯簿文件,可能包含上万条记录。

      ASP.NET在接收完此上传文件后,需要处理每条记录,然后插入到数据库,插入完成后,再绑定控件,将结果呈现给用户。

      插入上万条记录是一件相当费时的操作,如果同时上传的用户多的话,ASP.NET的线程池的 工作线程都可能会消耗光,从而导致“服务器不可用的错误”。

     解决方案:  使用异步页面(Asynchronous Pages),将耗时的操作(插入上万条记录)异步执行,

                      这样ASP.NET的工作线程可以继续服务其他的请求,到耗时的操作执行完后,再负责UI呈现的工作。

                      使用异步页面,还是不能解决用户响应慢的问题,只能提高服务器端性能,因此客户端使用进度条等方案,让用户等待的时候不会太枯燥。

                      关于异步页面:请参考http://msdn.microsoft.com/zh-cn/magazine/cc163725(en-us).aspx

    2.应用场景二: 

      对于一个实际的站点可能经常要做一些后台处理,如数据统计、评价、数据更新等操作,这些任务比较有规律,但是又比较耗时。

  解决方案

        1)将这些常用的任务直接记录到后台数据库或者MSMQ,由后台程序定时扫描来执行。

            我比较倾向的方式是写到数据库,比较直接,后台使用windows service或winform读取数据库,依次执行任务即可。

              而MSMQ感觉更容易扩展,详情请参考:http://www.codeproject.com/KB/dotnet/Using_MSMQ_ASPnet_Window.aspx

        2)采用Asp.net的定时处理方式,直接在WEB服务器层来进行处理。

           这种方式可能使用的比较少,请大家参考:http://hi.baidu.com/manly_001/blog/item/8474624a230f6d2508f7ef6c.html

3. 应用场景三

   场景三跟场景一比较相似,区别在于场景三只需要处理耗时的任务,而不需要呈现UI(如发送大批量的邮件),

   因此解决方案相对简单很多,而且不需要用户进行等待,可以直接返回,用户体验会比较好。

   解决方案

   1. 使用 System.Threading.ThreadPool类的QueueUserWorkItem方法缺点是会占用ASP.NET的工作线程(默认为25),会影响服务器端性能。

   2. 使用 delegate 然后调用BeginInvoke 方法,缺点同上。

   3. 使用System.Threading.Thread 类:

       Thread obj = new Thread(new ThreadStart(<function name with return type of VOID>));

      obj.IsBackground = true;

      推荐使用该方法,为了能够共享线程,可以自己实现线程池,参考http://www.codeproject.com/KB/threads/smartthreadpool.aspx

   后记

   由于代码因为商业原因不能拿出来共享,只能给大家找一些我参考的例子,非常抱歉。

   大家也可能会碰到一些其他的应用场景,或者有更好的解决方案,欢迎讨论。