使用隊列和線程對現有asp.net動態頁處理進行資源控制


IIS可以對ASP.NET站點進行一個資源控制,包括使用的CPU,處理進程數等.但如果想對某些動態頁面進行一個資源限制,只允許固定線程數量來處理某些動態請求,而不至於在某些情況個別的動態請求把整個站的資源都占光了.對於這么小的粒度控制顯然不適合由IIS來做,這個時候就可以通過asp.net提供IHttpAsyncHandler來解決這種事情.

處理結構

由於Asp.net提供了異步處理Handler,所以可以在Handler的Begin處理方法中把具體對象存放到隊列中,然后根據實際業務的需要來配置1-N個線程來處理相關請求.

IHttpAsyncHandler

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.

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來處理.

<handlers>
   <add name="custompage" verb="*" path="*.aspx" type="WebApp.Code.CustomPageFactory,WebApp"/>
</handlers>

隊列化處理

制定隊列的目的非常簡單就是有序可控地去處理一些工作,可以通過BeginProcessRequest的執行把請求先存放到了列中

public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
        {
            AspxAsyncResult result = new AspxAsyncResult(context, mHandler, cb);
            G_TaskQueue.Add(result);
            return result;
        }

制定線程處理

可以根據實際情況開啟1-N個線程來處理隊列中的工作.

private void OnRun(object state)
        {
                while (true)
                {
                    AspxAsyncResult asyncResult = Pop();
                    if (asyncResult != null)
                    {
                        asyncResult.Execute();
                    }
                    else
                    {
                        System.Threading.Thread.Sleep(10);
                    }
                }
        }

以上是固定線程去進行處理,但這樣的設計不好的地方就是沒有請求的時候線程會不停地做sleep工作,其實可以根據實際情況使用線程池來完成,具體就看情況來設計了.

總結

通過以上設計就可以輕易地對某些頁面請求進行一個資源控制.如果比較關心具體實現的朋友可以查看

http://blog.henryfan.net/post/2012/11/21/%E5%AE%9E%E7%8E%B0%E5%AF%B9%E7%8E%B0%E6%9C%89%E7%9A%84aspx%E8%AF%B7%E6%B1%82%E8%BF%9B%E8%A1%8C%E5%BC%82%E6%AD%A5%E9%98%9F%E5%88%97%E6%8E%A7%E5%88%B6%E5%A4%84%E7%90%86.aspx


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM