使用队列和线程对现有asp.net动态页处理进行资源控制
IIS可以对ASP.NET站点进行一个资源控制,包括使用的CPU,处理进程数等.但如果想对某些动态页面进行一个资源限制,只允许固定线程数量来处理某些动态请求,而不至于在某些情况个别的动态请求把整个站的资源都占光了.对于这么小的粒度控制显然不适合由IIS来做,这个时候就可以通过asp.net提供IHttpAsyncHandler来解决这种事情.
处理结构
由于Asp.net提供了异步处理Handler,所以可以在Handler的Begin处理方法中把具体对象存放到队列中,然后根据实际业务的需要来配置1-N个线程来处理相关请求.
IHttpAsyncHandler
1 2 3 4 5 6 7 8 9 10 11 12 | public interface IHttpAsyncHandler : IHttpHandler { /// <summary>Initiates an asynchronous call to the HTTP handler.</summary> /// <returns>An <see cref="T:System.IAsyncResult" /> that contains information about the status of the process.</returns> /// <param name="context">An <see cref="T:System.Web.HttpContext" /> object that provides references to intrinsic server objects (for example, Request, Response, Session, and Server) used to service HTTP requests. </param> /// <param name="cb">The <see cref="T:System.AsyncCallback" /> to call when the asynchronous method call is complete. If <paramref name="cb" /> is null, the delegate is not called. </param> /// <param name="extraData">Any extra data needed to process the request. </param> IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData); /// <summary>Provides an asynchronous process End method when the process ends.</summary> /// <param name="result">An <see cref="T:System.IAsyncResult" /> that contains information about the status of the process. </param> void EndProcessRequest(IAsyncResult result); } |
从代码来看IHttpAsyncHandler也是从IHttpHandler派生下来,并提供了Begin和End相关方法.
对已有页面进行异步封装
如果经常用IHttpHandler的朋友应该比较清楚这东西用于描述一个页面请求的,包括我们的aspx,而aspx默认处理的则是一个IHttpHandlerFactory实现System.Web.UI.PageHandlerFactory.通简单地继承System.Web.UI.PageHandlerFactory就可以让原来的aspx请求返回对应的异步的HttpHandler.
1 2 3 4 5 6 7 8 9 10 11 12 13 | public class CustomPageFactory : System.Web.UI.PageHandlerFactory { static CustomPageFactory() { } public override IHttpHandler GetHandler(HttpContext context, string requestType, string virtualPath, string path) { AspxAsyncHandler handler = new AspxAsyncHandler( base .GetHandler(context, requestType, virtualPath, path)); return handler; } } |
PageFactory实现后只需要简单地配置一个web.config文件就可以让现有的aspx处理由异步Handler来处理.
1 2 3 | < handlers > < add name="custompage" verb="*" path="*.aspx" type="WebApp.Code.CustomPageFactory,WebApp"/> </ handlers > |
队列化处理
制定队列的目的非常简单就是有序可控地去处理一些工作,可以通过BeginProcessRequest的执行把请求先存放到了列中
1 2 3 4 5 6 | public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) { AspxAsyncResult result = new AspxAsyncResult(context, mHandler, cb); G_TaskQueue.Add(result); return result; } |
制定线程处理
可以根据实际情况开启1-N个线程来处理队列中的工作.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | private void OnRun( object state) { while ( true ) { AspxAsyncResult asyncResult = Pop(); if (asyncResult != null ) { asyncResult.Execute(); } else { System.Threading.Thread.Sleep(10); } } } |
以上是固定线程去进行处理,但这样的设计不好的地方就是没有请求的时候线程会不停地做sleep工作,其实可以根据实际情况使用线程池来完成,具体就看情况来设计了.
总结
通过以上设计就可以轻易地对某些页面请求进行一个资源控制.如果比较关心具体实现的朋友可以查看
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
2012-05-21 开源网络文件管理工具SmarkNetDisk