Joe
Joe

Reputation: 1885

PageAsyncTask without blocking page load

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?

Upvotes: 0

Views: 2711

Answers (2)

mason
mason

Reputation: 32703

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

Upvotes: 3

Joe
Joe

Reputation: 1885

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>

Upvotes: 0

Related Questions