4

I thought the GetData task registered in Page_Load won't block the loading of Index.aspx, since it's an async task; 5 seconds after the page is rendered, the lblData is set and reflected on the Index.aspx.

However, in my case, the loading of Index.aspx is blocked for 5 seconds, waiting for the async GetData to be finished. Only after 5 seconds is the Index.aspx rendered.

Is this expected? Or the GetData is running synchronously because I did something wrong?

// Index.aspx.cs
public partial class Index : Page
{
    protected string lblData;
    protected void Page_Load(object sender, EventArgs e)
    {
        RegisterAsyncTask(new PageAsyncTask(GetData));
        ExecuteRegisteredAsyncTasks();
    }

    public async Task GetData()
    {
        await Task.Delay(5000);
        lblData = "Hello world!";
    }
    // ...
}

I've added Async="true" to Index.aspx.

lzl124631x
  • 4,485
  • 2
  • 30
  • 49
  • The details RegisterAyncTask might help https://msdn.microsoft.com/en-us/library/system.web.ui.page.registerasynctask(v=vs.110).aspx – Eldho Apr 26 '16 at 11:07
  • Take a look at similar http://stackoverflow.com/q/31567515/1876572 stating that `"Methods hooked up with RegisterAsyncTask will run immediately after PreRender.` – Eldho Apr 26 '16 at 11:12

3 Answers3

4

"Asynchronous" is a modifier. You always have to ask "asynchronous with respect to what?"

In this case, the task is asynchronous with respect to the worker threads servicing the requests. The important point is that you don't need to block a request thread while processing most kinds of asynchronous tasks, so your server will ceteris paribus be able to service more requests concurrently while possibly using less resources to do so.

It's not asynchronous with respect to page rendering on the client, or even the single request itself - the request processing is still entirely synchronous, and will only be sent when the whole response is ready (unless you use explicit Flushes, but that's a whole another can of worms). In fact, the whole point of await is to allow your code to behave as if it were synchronous, while being asynchronous with respect to threads, I/O, UI, what have you. await is the explicit synchronization point.¨

In fact, that's exactly why you're using the asynchronous infrastructure in the first place. If you used asynchronous tasks without RegisterAsyncTask, the request would end before the response was completely done. The infrastructure allows you to release the worker threads while you don't need them, while still keeping all the relevant request context ready for the time you come back from your asynchronous work. It's similar to using await in the Main method of a console application - if the infrastructure isn't ready, await just means return someTask; without the "and get back here when the task is done".

If you want something that doesn't block the processing of the request, it must be asynchronous with respect to the request. For example, the page can send a separate AJAX request to the server to provide more data.

Luaan
  • 62,244
  • 7
  • 97
  • 116
2

According to MSDN, you are doing everything correctly. I assume that you're incorrectly assuming that the page will be loaded / rendered and returned to the client before the asynchronous operation defined in the GetData function is finished -- if so that is incorrect.

The lifecycle (while async) still doesn't return to the client until all the work is done. Here is a SO Q & A that might make more sense. An even better explanation from Scott Hanselman here.

Community
  • 1
  • 1
David Pine
  • 23,787
  • 10
  • 79
  • 107
0

It is probably running asynchronously, but it is still "code behind", and code behind will be run and finished on the server before any rendered Page is sent to the browser.

If you want your grid to fill dynamically after the page has loaded on the browser, you need to use JavaScript and WebMethods or WebAPI or something similar.

Alexander
  • 2,457
  • 1
  • 14
  • 17