Container.RetrieveItems() calls a service which takes a while so I would like to call it asynchronously (after the items are retrieved they are set to the List property of the Container class). Upon completion of retrieving the items, I would like it to update a gridView which is inside an updatePanel (updatePanel Mode="Conditional" and ScriptManager EnablePartialRendering="true". UpdatePanel has no trigger items).
I have set breakpoints and stepped through each step. The items are retrieved, grid is databound then it calls update. No exceptions are being thrown but the grid is not updating with the content. If I set the UpdatePanel to update using a trigger and Timer.OnTick event it works perfect, however I only need it to update after the items are retrieved so firing the manual UpdatePanel.Update() upon completion of the service call would be ideal.
I have done quite a bit of searching, but all the answers are 'You forgot to call DataBind()'
Is there anything I am missing?
private void UpdateGrid()
{
grid.DataSource = Container.List;
grid.DataBind();
updatePanel.Update();
}
protected void Page_Load(object sender, EventArgs e)
{
var task = Task.Factory.StartNew(Container.RetrieveItems);
task.ContinueWith((x) => UpdateGrid());
}
Update: I set up a simpler test to try to identify the issue. I created a label whose Text property would be updated upon completion of a method. When the page loaded, it called the method and when the method finished it called updatePanel.Update() but no change.
Per Jaimes' advice, I then tried calling the manual update inside the postback of a Button_click and it did indeed update the label. So that is why my current setup is not working, although I'm still searching for the best way to update content on completion of an asynchronous task.
Jamie is on the right track. Your server cannot "push" new data to the client after the page is rendered. The client has to initiate a request. I would set a timer or use a JavaScript
setTimeouton the client to regularly poll the server to see if it completed.Web Service Approach
Another approach is to set up a web service on the server, then call it from your page. This will be executed in a new thread and update the grid asynchronously as soon as results are available.
First you need to set up a WCF Web Service. There are thousands of articles about this if you aren't sure. Here is one of them: http://www.codeproject.com/Articles/16973/Simple-Web-Service-using-WCF-Windows-Communication
Here is some sample code from one of my projects:
Calling the web service from the client
Next you will need to databind the grid from your page, using JavaScript: http://blog.ashmind.com/2007/06/21/client-side-databinding-with-aspnet-ajax-futures/
Here is some sample code from the same project. This project uses jQuery and not pure JavaScript like the samples in the links:
References http://aspalliance.com/1301_Unveil_the_Data_Binding_Architecture_inside_Microsoft_ASPNET_Ajax_10__Part_1
http://aspalliance.com/1301_Unveil_the_Data_Binding_Architecture_inside_Microsoft_ASPNET_Ajax_10__Part_2