2

Why is the following ASP.NET code using PageAsyncTask executes in total of 8 seconds regardless if I run it as is or if I comment 2 lines with PageAsyncTask and un-comment Thread.Sleep(5000) in Page_load?:

//PageAsyncTask asyncTask1 = new PageAsyncTask(BeginAsyncOperation, EndAsyncOperation,
OperationTimeOut, arr, true); //Page.RegisterAsyncTask(asyncTask1);

Thread.Sleep(5000);

I understand that PageAsyncTask runs a task in parallel to other tasks and that should make overall process of page loading faster in this case. What am I missing?

public partial class _Default : System.Web.UI.Page
{
    public delegate string foo(string param1, string param2);
    public IAsyncResult BeginLongRunningTransaction(AsyncCallback cb, object state)
    {
        var arr = (string[])state;
        string z1 = arr[0];
        string z2 = arr[1];

        foo method = this.LongRunningTransaction;
        return method.BeginInvoke(z1, z2, cb, state);
    }
    protected void Page_Load(object sender, EventArgs e)
    {
        Response.Write(DateTime.Now.ToString() + "<br/>");
        string[] arr = { "Zorik1", "Zorik2" };


        // if I comment following two lines and un-comment
        // Thread.Sleep(5000) command the process runs 8 sec. regardless
        PageAsyncTask asyncTask1 = new PageAsyncTask(BeginAsyncOperation, EndAsyncOperation, OperationTimeOut, arr, true);
        Page.RegisterAsyncTask(asyncTask1);


        //Thread.Sleep(5000);
        Thread.Sleep(1000);
        Thread.Sleep(1000);
        Thread.Sleep(1000);
    }

    private IAsyncResult BeginAsyncOperation(object sender, EventArgs e,
     AsyncCallback cb, object state)
    {
        return this.BeginLongRunningTransaction(cb, state);
    }

    private string LongRunningTransaction(string param1, string param2)
    {
        Thread.Sleep(5000);
        txtAsync.Text = "Updated";
        updPnl1.Update();
        return "this is return string";
    }


    private void EndAsyncOperation(IAsyncResult ar)
    {

    }

    private void OperationTimeOut(IAsyncResult asyncResult)
    {
        string a = "";
    }

    protected void Page_PreRender(object s, EventArgs e)
    {
        string a = "";
        Response.Write(DateTime.Now.ToString() + "<br/>");
    }

    protected void Page_PreRenderComplete(object s, EventArgs e)
    {
        Response.Write(DateTime.Now.ToString() + "<br/>");
    }

}
user1112906
  • 61
  • 1
  • 8

1 Answers1

3

That's because you aren't actually running anything in parallel - all PageAsyncTask are run on ExecuteRegisteredAsyncTasks() page method call, and that happens automatically right after Page_PreRender ends (and Page_PreRenderComplete starts after all tasks finish or timeout): http://msdn.microsoft.com/en-us/library/system.web.ui.pageasynctask.aspx

Any asynchronous tasks registered before the PreRenderComplete event will be executed automatically by the page if they have not already been executed. Those asynchronous tasks registered after the PreRenderComplete event must be executed explicitly through the ExecuteRegisteredAsyncTasks method. The ExecuteRegisteredAsyncTasks method can also be used to start tasks before the PreRenderComplete event. The ExecuteRegisteredAsyncTasks method executes all the registered asynchronous tasks on the page that have not been executed.

So, you would have to manually call ExecuteRegisteredAsyncTasks() (can be safely called any number of times) in Page_Load before any Thread.Sleep() starts. Or put every Thread.Sleep() in different PageAsyncTask - but make sure that the fifth parameter (for parallel execution) is true, and that page async directive is set: <%@ Page Async="true" %>

Nikola Bogdanović
  • 3,206
  • 1
  • 20
  • 28