0

I am trying to find a way to perform an asynchronous method in the Page_Load method of a webforms page, without blocking the page load for the user. I am using the following code:-

C# Code behind

public partial class _Default : Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        RegisterAsyncTask(new PageAsyncTask(AsyncDatabind));
    }

    private async Task AsyncDatabind()
    {
        await Task.Delay(5000);
        Test.Text = "Hello!";
    }
}

ASPX view

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="AsyncTest._Default" Async="true"%>

<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
    <asp:Label ID="Test" runat="server"></asp:Label>
</asp:Content>

Ideally, the page should load for the user, then after the async task completes, the label is updated. So the page should be visible for 5 seconds before the label text is set. Is this possible using PageAsyncTask?

MatthewMartin
  • 32,326
  • 33
  • 105
  • 164
Joe
  • 1,847
  • 2
  • 17
  • 26
  • 1
    Only with ajax! WebForms is completely rendered at server without any UpdatePanel or other ajax controls. Then, you will get the entire page after the delay you did. – Fals Jul 28 '15 at 13:37

2 Answers2

3

All server side code from your page, whether async or not, will execute and only then will the results be rendered to HTML and sent to the client. So for the client, what you're doing isn't helping anything.

Instead, what you want to focus on is getting the initial content to the client first, and then using AJAX to make subsequent requests to the server. That ideally means you have as little as possible in your Page_Load or any other methods that might run on the initial request.

Unlike Joe, I do not recommend using UpdatePanel, as that's going to bring you a lot of headaches further down the road. Instead, learn to use a lower abstraction of AJAX, such as jQuery AJAX, Zepto.js AJAX, or Angular's HTTP service. For the server to respond to these requests, implement ASP.NET Web API or HTTP handlers.

You'll find that many of the techniques used in Single Page Applications will be handy, but you don't have to go full-SPA to achieve your goal. SPA diagram

mason
  • 31,774
  • 10
  • 77
  • 121
  • Is it possible to update a control on a webforms page using jquery/zepto/angular ajax? I can only find how to implement static server side handlers that have no access to the page controls. – Joe Jul 28 '15 at 14:19
  • @Joe Sure is possible. ASP.NET controls end up as rendered HTML elements on the client, and those AJAX libraries know how to use them. The only thing you want to be aware of is that the control ID's are by default different on the client. One way to fix that is to add `ClientIdMode="static"` to all the controls you plan to reference from your client side code. – mason Jul 28 '15 at 14:26
0

As noted by Fals, this can be achieved with an UpdatePanel.

C# Code Behind

public partial class _Default : Page
{
    public bool Loaded { get; set; }

    protected void Page_Load(object sender, EventArgs e)
    {

    }

    private async Task AsyncDatabind()
    {
        await Task.Delay(5000);
        Test.Text = "Hello!";
        Loaded = true;
    }

    protected void Panel_Load(object sender, EventArgs e)
    {
        if(IsPostBack && !Loaded)
            RegisterAsyncTask(new PageAsyncTask(AsyncDatabind));
    }
}

ASPX view

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="AsyncTest._Default" Async="true"%>

<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
    <asp:UpdatePanel ID="Panel" ClientIDMode="AutoID" runat="server" OnLoad="Panel_Load">
        <ContentTemplate>
            <asp:Label ID="Test" runat="server"></asp:Label>
        </ContentTemplate>
    </asp:UpdatePanel>

    <script>
        <%if(!Loaded){%> $(document).ready(function () { __doPostBack('Panel', ''); }); <%}%>
    </script>
</asp:Content>
Community
  • 1
  • 1
Joe
  • 1,847
  • 2
  • 17
  • 26