asp.net 2.0頁面效能的考慮–非同步頁面處理模型

來源:互聯網
上載者:User
   一般情況下我們通常在一個頁面中,結合頁面事件處理模型,按順序一步一步的聲明各個處理過程。這就是所說的同步處理(Synchronous),我們可以很方便的定義頁面處理的順序。同步處理雖然很方便,但在耗時高請求處理的時候就會暴露嚴重的問題,在一個高並發的網站生產伺服器上,由於.net處理是基於所謂的ThreadPool的,而Threadpool中的處理線程又是有限的,如果當前ThreadPool中的線程已經全部用盡,而後繼又有不斷的大規模請求的話,伺服器的效能就會嚴重的下降,更嚴重的還會使伺服器崩潰。所以我們關心最多的就是怎樣來更好的使用的.net ThreadPool。讓.net更好的發揮的效能。

    說到這就不得不談.net的非同步處理(Asynchronous),模型一般為BeginXXX,EndXXX,BeginXXX返回一個IAsycResult對象,其中包含對當前非同步作業的資訊,而EndXXX使用者接受傳回值,輸出參數。.net從ThreadPool中分配一個空閑線程給BeginXXX然後立即返回給ThreadPool,等到非同步處理結束時,.net又從ThreadPool中分配一個空閑線程用於處理EndXXX方法。這樣就可能有足夠的線程用於處理其它的事情。見於篇幅問題這裡我們只談asp.net 2.0的非同步處理模型,我們都知道在1.x的時候要很好的建立頁面的非同步處理是比較麻煩的,可能微軟很早就認識到了這一點,所以在2.0的版本中引入的新的頁面處理模型,加入了方便的非同步處理點(Asynchronous Point)在PreRender事件和PreRenderComplete事件之間,在這個非同步點,頁面需要等待所有的非同步處理都完成,所以可以在頁面呈現之前完成你需要的任何效果,極大簡化了建立非同步頁面的方法。

   首先你要在建立頁面的@page聲明中加入 Async="true",這是必須的。設定告訴asp.net要選用IHttpAsyncHandler來處理當前的頁面。接下來你需要做的一般是在Page_Load事件處理中使用非同步處理過程,現在有兩種途徑:

   第一種就是使用Page.AddOnPreRenderCompleteAsync方法來處理需要非同步處理的Begin和End方法集.如下:

AddOnPreRenderCompleteAsync(new BeginEventHandler(MyBeginMethod),new EndEventHandler(myEndMethod));
通過添加上面的方法後,頁面執行通常的生命週期事件直到頁面的PreRender事件觸發.然後Asp.net調用先前在AddOnPreRenderCompleteAsync中的註冊的Begin處理常式。通常在Begin處理常式中處理的是一些非同步web服務,IO以及SQL的處理,這樣就可以極大的緩解.net線程池的壓力。例如:
<%@ Page Async="true" Language="C#"  %>
<asp:Content ID="Content" ContentPlaceHolderID="Main" Runat="server">
    <asp:Label ID="Output" Runat="server"></asp:Label>
</asp:Content>

public partial class AsyncPage : System.Web.UI.Page
{
    private WebRequest m_Request;

    void Page_Load (object sender, EventArgs e)
    {
        AddOnPreRenderCompleteAsync (
            new BeginEventHandler(BeginAsyncOperation),
            new EndEventHandler (EndAsyncOperation)
        );
    }

    IAsyncResult BeginAsyncOperation (object sender, EventArgs e, AsyncCallback cb, object state)
    {
        m_Request = WebRequest.Create("http://www.dofor.cn");
        return m_Request.BeginGetResponse (cb, state);
    }

    void EndAsyncOperation (IAsyncResult ar)
    {
        string text;
        using (WebResponse response = m_Request.EndGetResponse(ar))
        {
            using (StreamReader reader = new StreamReader(response.GetResponseStream()))
            {
                text = reader.ReadToEnd();
            }
        }

        Regex regex = new Regex ("href\\s*=\\s*\"([^\"]*)\"", RegexOptions.IgnoreCase);
        MatchCollection matches = regex.Matches(text);

        StringBuilder builder = new StringBuilder(1024);
        foreach (Match match in matches)
        {
            builder.Append (match.Groups[1]);
            builder.Append("<br/>");
        }

        Output.Text = builder.ToString ();
    }
}

   第二中就是註冊非同步任務(Register Asynchronous Task).RegisterAsyncTask比AddOnPreRenderCompleteAsync具有更大的靈活性和更多的優勢。它可以允許你聲明一個逾時參數,同樣可以聲明在@Page中如:AsyncTimeout="5",以秒為單位,但要注意的是這裡聲明不是每個非同步處理過程的逾時而是整個頁面的處理時間逾時。同樣.net framework 2.0還為註冊任務引入了新的MethodAsync,MethodAsync就是為了方便處理多個非同步過程的。例如:
<%@ Page Async="true" Language="C#"  %>
<asp:Content ID="Content" ContentPlaceHolderID="Main" Runat="server">
    <asp:Label ID="Output" Runat="server"></asp:Label>
</asp:Content>

public partial class AsyncPageTask : System.Web.UI.Page
{
    private WebRequest m_Request;

    protected void Page_Load(object sender, EventArgs e)
    {
        PageAsyncTask task = new PageAsyncTask(
            new BeginEventHandler(BeginAsyncOperation),
            new EndEventHandler(EndAsyncOperation),
            new EndEventHandler(TimeoutAsyncOperation),
            null
        );

        RegisterAsyncTask(task);
    }

    IAsyncResult BeginAsyncOperation(object sender, EventArgs e, AsyncCallback cb, object state)
    {
        m_Request= WebRequest.Create("http://www.dofor.cn");
        return m_Request.BeginGetResponse(cb, state);
    }

    void EndAsyncOperation(IAsyncResult ar)
    {
        string text;
        using (WebResponse response = m_Request.EndGetResponse(ar))
        {
            using (StreamReader reader = new StreamReader(response.GetResponseStream()))
            {
                text = reader.ReadToEnd();
            }
        }

        Regex regex = new Regex("href\\s*=\\s*\"([^\"]*)\"", RegexOptions.IgnoreCase);
        MatchCollection matches = regex.Matches(text);

        StringBuilder builder = new StringBuilder(1024);
        foreach (Match match in matches)
        {
            builder.Append(match.Groups[1]);
            builder.Append("<br/>");
        }

        Output.Text = builder.ToString();
    }

    void TimeoutAsyncOperation(IAsyncResult ar)
    {
        Output.Text = "當前資料不可用";
    }
}

總之合理的利用asp.net 2.0的非同步處理,就可以極大的改善您大輸送量高並髮網站頁面的效能。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.