.NET本質論(4)應用程式對象HttpApplication

来源:http://www.cnblogs.com/haofaner/archive/2016/01/04/5098071.html
-Advertisement-
Play Games

當HttpContext對象創建之後,HttpRuntime將隨後創建一個用於處理請求的對象,這個對象的類型為HttpApplication. 在ASP.NET內部,HttpRuntime管理一個定義在System.Web命名空間下的HttpApplicationFactory類的實例...


    當HttpContext對象創建之後,HttpRuntime將隨後創建一個用於處理請求的對象,這個對象的類型為HttpApplication.
     在ASP.NET內部,HttpRuntime管理一個定義在System.Web命名空間下的HttpApplicationFactory類的實例,HttpApplicationFactory通過工廠模式管理HttpApplication對象,在HttpApplicationFactory內部維護了一個HttpApplication對象池,使得被創建的HttpApplication對象可以被重覆使用,但是,每一個HttpApplication對象每一次僅僅用於處理一個請求,這樣,對於ASP.NET程式員來說,也就不需要考慮HttpApplication中多個請求併發的處理問題了。
 在實際的請求處理過程中,我們還需要進行大量的工作,例如,檢查當前的請求是由哪一個用戶發起的,以此我們就可以針對不同的用戶進行不同的處理,或者根據用戶來決定是否對用戶的請求進行處理,對於沒有許可權的用戶返回一個缺少相應許可權的回應等。如果我們在一個方法中來完成這些任務,顯然會造成方法的過度臃腫。在HttpApplication中,利用.NET中的事件機制,通過在處理過程中依次發出的多個事件,將這個處理過程分解為多個步驟,這個處理機制通常我們稱為處理管道,下麵我們將會詳細討論處理管道的內在機制和HttpApplication的多個事件。
    1.處理管道
     所謂的處理管道,就是處理複雜問題的時候,將處理的過程分解為多個處理步驟,我們將這種經過多個步驟的處理方式稱為處理管道。在.NET中,藉助於事件的強大威力,我們可以通過處理管道將複雜的處理步驟封裝起來,通過事件將處理過程 的多個步驟給程式員以便於程式員對管理管道進行擴展。如下圖概述了HttpApplication處理管道的工作過程。


     對於一個管道來說,它往往要暴露出大量的事件,通過這些事件,提供程式員的擴展機制。但是,對於一具有著眾多事件的類來說,定義大量的事件意味著創建對象的時候需要付出創建事件的成本,因為在.NET中,所謂的事件就是一個受限制的委托成員,定義多個事件,意味著在創建的對象中將會需要更多的存儲空間。針對這個問題,在System.ComponentModel.Component類中,提供了處理多個事件的基礎:Events屬性,它的類型為System.ComponentModel.EventHandlerList,這是一個線性的字典,當需要事件的時候, 就通過key將事件保存到集合中,沒有對應的事件,就不會付出創建事件的成本,這樣,通過EventHandlerList可以在一個集合中管理多個事件對象,節省對象占用的空間,它的主要成員如下:

 

 

在使用的時候,首先從Component派生一個類,這個類將繼承Component的Events集合屬性。對於這個派生類所需要定義的每一個類,這個類將繼承Component的Event集合屬性。對於這個派生類所需要定義的每一個事件,在類中定義一個對應的作為Key的對象,以後,通過這個Key對象來訪問由Events集合管理的事件。
 程式員也可以自己在類中定義一個類似的字典來完成這個任務,並不一定要從Component類中派生。如下

 

 

 public class ProcessPipeline : System.ComponentModel.Component
    {
        #region
        private static readonly object startEvent = new object();
        private static readonly object preProcessEvent = new object();
        private static readonly object postProcessEvent = new object();
        private static readonly object endEvent = new object();
        #endregion

        #region
        public event EventHandler StartProcess
        {
            add { this.Events.AddHandler(startEvent, value); }
            remove { this.Events.RemoveHandler(startEvent, value); }
        }
        public event EventHandler PreProcess
        {
            add { this.Events.AddHandler(preProcessEvent, value); }
            remove { this.Events.RemoveHandler(preProcessEvent, value); }
        }
        public event EventHandler PostProcess
        {
            add { this.Events.AddHandler(postProcessEvent, value); }
            remove { this.Events.RemoveHandler(postProcessEvent, value); }
        }
        public event EventHandler EndProcess
        {
            add { this.Events.AddHandler(endEvent, value); }
            remove { this.Events.RemoveHandler(endEvent, value); }
        }
        #endregion



        #region
        protected void OnStartProcess(EventArgs e)
        {
            if (this.Events[startEvent] != null)
            {
                (this.Events[startEvent] as EventHandler)(this, e);
            }
        }


        protected void OnPreProcess(EventArgs e)
        {
            if (this.Events[preProcessEvent] != null)
            {
                (this.Events[preProcessEvent] as EventHandler)(this, e);
            }
        }


        protected void OnPostProcess(EventArgs e)
        {
            if (this.Events[postProcessEvent] != null)
            {
                (this.Events[postProcessEvent] as EventHandler)(this, e);
            }
        }


        protected void OnEndProcess(EventArgs e)
        {
            if (this.Events[endEvent] != null)
            {
                (this.Events[endEvent] as EventHandler)(this, e);
            }
        }
        #endregion

        public void Process()
        {
            Console.WriteLine("開始處理");
            this.OnStartProcess(EventArgs.Empty);
            Console.WriteLine("準備處理");
            this.OnPreProcess(EventArgs.Empty);
            Console.WriteLine("下在處理中。。。");
            this.OnPostProcess(EventArgs.Empty);
            Console.WriteLine("處理結束");
            this.OnEndProcess(EventArgs.Empty);
        }
    }

 

 

 

 

namespace 自定義事件管道
{
    class Program
    {
        static void Main(string[] args)
        {

            ProcessPipeline process = new ProcessPipeline();
            process.StartProcess
                += new EventHandler(process_StartProcess);
            process.StartProcess
                += new EventHandler(process_StartProcess1);
            process.StartProcess
                -= new EventHandler(process_StartProcess);
            process.PreProcess
                += new EventHandler(process_PreProcess);
            process.PostProcess
                += new EventHandler(process_PostProcess);
            process.EndProcess
                += new EventHandler(process_EndProcess);
            process.Process();
            Console.ReadLine();
        }
        static void process_StartProcess(object sender, EventArgs e)
        {
            Console.WriteLine("開始處理的事件中的處理。。。");
        }


        static void process_StartProcess1(object sender,EventArgs e)
        {
            Console.WriteLine("開始處理的事件前的事件中的處理1");
        }

        static void process_PreProcess(object sender, EventArgs e)
        {
            Console.WriteLine("處理前的事件中的處理。。。");
        }
        static void process_PostProcess(object sender, EventArgs e)
        {
            Console.WriteLine("正在處理的事件中處理中。。。。");
        }
        static void process_EndProcess(object sender, EventArgs e)
        {
            Console.WriteLine("處理完成的事件處理。。。");
        }
    }
}

 在ProcessPipeline類中,定義了4個事件,首先需要註意的是在類中並沒有定義4個實際的委托成員來對應事件,通過從Component派生,實際上從基類繼承了一個EventHandlerList類型的成員,通過將事件以屬性的形式來定義,並映射到EventHandlerList中不管在類中定義了多少個事件,在創建的對象實例中只需要這樣一個EventHandlerList的對象來保存事件響應的委托對象。
其次,在Process方法中,模擬了處理的過程,在處理的過程中,通過調用觸發事件的On開頭的方法,以事件的形式將處理的步驟暴露給程式員。
使用這個類的時候,對於程式員關心的處理事件,可以通過註冊事件處理方法到相應的事件上,在ProcessPipeline進行處理的過程中,相應的事件處理方法會被調用。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 增加節點時,我們是這樣寫的:xop.Document.Element("messages").Add( new XElement("message", new XAttribute("event", ...
  • 經過十多天的艱苦奮戰,MyKTV點歌系統終於成型,從剛開始接到項目的茫然,到完成項目時的喜悅,整個過程的艱辛和付出只有自己知道.雖然這個項目還有許多需要完善的地方,譬如添加歌詞信息,實現窗體的美化等,這些在後續時間里我再一一進行一個完善吧!首先呢,我先將整個項目所能實現的功能做一個簡單的介紹,K.....
  • 配置代碼: 異常信息: [Error] An unhandled exception was thrown by the application.System.Security.Cryptography.CryptographicException: An error occurred while ...
  • 在web頁面上我們可以通過frameset,iframe嵌套框架很容易實現各種導航+內容的佈局界面,而在winform、WPF中實現其實也很容易,我這裡就分享一個:在winform下實現左右佈局多視窗界面。我這裡說的多視窗是指一個父視窗包含多個子視窗,在winform中實現這種效果很簡單,即將某個窗...
  • 最近對UWP開發比較感興趣,大概瞭解之後覺得有必要回顧一下xaml相關內容。。於是抽時間把以前學WPF的相關材料搜羅了一下順便和新的xaml特性做了一個小總結。。希望能堅持寫下去吧。。O(∩_∩)O~ 個人覺得還是從比較零散的xaml佈局開始寫比較合適,這部分直接決定了應用程式的實用性,尤其是在出....
  • 繼上次的前臺內容今天我們來講一講後臺的一些事兒吧!後臺呢主要是對前臺的歌手、歌曲信息及圖片、歌曲路徑的一些~嗯~算是配置吧! 還是先看效果圖 後臺效果圖 登錄界面 主界面 添加歌手 該窗體填寫歌手信息並選擇圖片後會將歌手的信息保存在資料庫並且將選中的圖片複製到資料庫中存放歌手圖像的制定路徑中! 查詢...
  • FrameSet框架集
  • 之前我在一篇blog中寫過如何使用多語言工具包,見http://www.cnblogs.com/yanxiaodi/p/3800767.html在WinEcos社區也發佈過一篇詳細的文章介紹多語言工具包的使用,但因社區改版那篇文章已經找不到了。當時寫的時候還沒有出Win10的SDK,都是基於UAP框...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...