title: Calling RegisterAsyncTask on an async method
body: <p>I posted a previous problem (<a href="https://stackoverflow.com/questions/44285371/asp-net-updatepanel-with-usercontrols-and-page-level-async-method">asp.net UpdatePanel with UserControls and Page Level Async Method</a>), and think I have narrowed down my issue to a separate question.</p>
  
  <p>I have an asp.net page, which needs to call an async method from a library.</p>
  
  <p>I load the page as follows:</p>
  
  <pre><code>Private _dlgt As AsyncTaskDelegate
  Protected Delegate Sub AsyncTaskDelegate()
  
   Protected Sub Page_Load(ByVal sender As Object, ByVal e As 
      Dim LoadTask As New PageAsyncTask(AddressOf OnBegin, AddressOf OnEnd, AddressOf OnTimeout, "AsyncTask1", True)
      Page.RegisterAsyncTask(LoadTask)
  End Sub
  
  Public Function OnBegin(ByVal sender As Object, ByVal e As EventArgs, ByVal cb As AsyncCallback, ByVal extraData As Object) As IAsyncResult
      _dlgt = New AsyncTaskDelegate(AddressOf Update)
      Dim result As IAsyncResult = _dlgt.BeginInvoke(cb, extraData)
      Return result
  End Function
  
  Private Async Function Update() As Task
      Dim AController As New CIP_WS.ARFController
      Dim ARFTask As Task(Of CIP_WS.ARF) = AController.GetARFWithResultsAsync(Client.ClientID, PRN, Nothing, StartTime, EndTime, CIP_WS.LabResultController.InequalityModes.AsIs)
      ARF = Await ARFTask
      PrintResults()
  End Function
  </code></pre>
  
  <p>The problem (I think), is that I have to set the page attribute to async=true, as I need to await a task.  However (according to MS), if i set the attribute to true, the whole page will be processed asynchronously.  If set to false, "the thread that executes the page will be blocked until all asynchronous tasks are complete".  The latter is what I need, as it is loading and displaying the page, before the data (i.e before the update async method returns), and I am only getting placeholders.</p>
  
  <p>To be clear, the Update method never completes.  The Page_Load always complete without await the method to finish.</p>
  
  <p>I feel so close, but far on getting this to work now.  Any help, much appreciated.</p>
  
  <p>EDIT____</p>
  
  <p>Firstly thanks for the responses so far.</p>
  
  <p>I have tried the following code previously and it 90% works, but thanks for the suggestion.</p>
  
  <pre><code>    Dim LoadTask As New PageAsyncTask(AddressOf Update)
      Page.RegisterAsyncTask(LoadTask)
  </code></pre>
  
  <p>It is probably my own fault, but I have been trying to keep the problem simple, but it is bigger than this.</p>
  
  <p>The code above only 90% works, because it loads the data async fine, and then the page renders and loads as expected.  However, I have some dynamic user-controls, which also load fine initially, but do not behave correctly during postbacks.  In this case, when a user click a button, it does not change the visibility of a panel within the specific user-control.  I have fully documented the issue on the link to another SO question above, but in short it works fine when I do not use async, but not when I have an async call during load.</p>
  
  <p>I moved on to another part of the project , while I took a break from that problem, and started async-ing another part of the site.  Again, I hit more dynamic user-controls, but this time the async call was in the load of the user-control rather than the page.  I had exactly the same issue, except it was a drop down not persisting selections, rather than a panel visibility not persisting.  I figured out I needed to call the asyn method in the following way</p>
  
  <pre><code> Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
  
      Dim LoadTask As New PageAsyncTask(AddressOf OnBegin, AddressOf OnEnd, AddressOf OnTimeout, "AsyncTask1", True)
              Dim LoadTask As New PageAsyncTask(AddressOf OnBegin, AddressOf OnEnd, AddressOf OnTimeout, "AsyncTask1", True)
  
      Page.RegisterAsyncTask(LoadTask)
      Page.ExecuteRegisteredAsyncTasks()
  
      PrintGraph()
  
      End If 
    End Sub
  </code></pre>
  
  <p>It was both manually passing true to force parallel processing, and calling ExecuteRegisteredAsyncTasks that fixed it for the cuser-ontrols and this page as a whole.  It now works perfectly async.  The only extra thing I did have to do, which effects other async calls in the project was add the following to the config:</p>
  
  <pre><code>    &lt;add key="aspnet:UseTaskFriendlySynchronizationContext" value="false" /&gt;
  </code></pre>
  
  <p>The only bummer with this is, I have to call all PageAsyncTask using the fully overloaded method (onLoad,OnEnd,OnTimeOut,State,Parallel), rather than just passing the main method.  I think due to having to handle the TimeOut manually after adding the key, but I am not sure.</p>
  
  <p>Sooo... I then tried to take this knowledge to help with my original issue, and it is still not having it!</p>
  
  <p>So I can either:</p>
  
  <p>1) Use the following, load the data async, and load the page fine initially, but any postback reverts user-controls back to original state.  This would also have a knock on effect to the other async issue I had, which meant all future async tasks needed to be registered as per item 2, so this would re-break that now working page.</p>
  
  <pre><code>    Dim LoadTask As New PageAsyncTask(AddressOf Update)
      Page.RegisterAsyncTask(LoadTask)
  </code></pre>
  
  <p>2) Use the following, which does not wait for the registered async method to complete (from what I can tell), so loads the webpage without essentially updating any controls.  As per a comment, I accept there maybe something else wrong, that I have failed to do.</p>
  
  <pre><code>     Protected Sub Page_Load(ByVal sender As Object, ByVal e As 
       Dim LoadTask As New PageAsyncTask(AddressOf OnBegin, AddressOf OnEnd, AddressOf OnTimeout, "AsyncTask1", True)
      Page.RegisterAsyncTask(LoadTask)
      End Sub
  </code></pre>
  
  <p>I can make this work to the same extent as item 1, if I don't use the IAsyncResult approach as per MS docs, and just call the method for OnBegin, but this still has the same issue as 1.</p>
  
  <pre><code>     Protected Sub Page_Load(ByVal sender As Object, ByVal e As 
       Dim LoadTask As New PageAsyncTask(AddressOf Update, AddressOf OnEnd, AddressOf OnTimeout, "AsyncTask1", True)
      Page.RegisterAsyncTask(LoadTask)
      End Sub
  </code></pre>
  
  <p>it should be noted I can use the IAsyncResult approach successfully in the other page scenario where the user-control is calling the async load method.</p>
  
  <pre><code>    Private _dlgt As AsyncTaskDelegate
      Protected Delegate Sub AsyncTaskDelegate()
  
      Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
  
      Dim LoadTask As New PageAsyncTask(AddressOf OnBegin, AddressOf OnEnd, AddressOf OnTimeout, "AsyncTask1", True)
  
      Page.RegisterAsyncTask(LoadTask)
      Page.ExecuteRegisteredAsyncTasks()
  
      PrintGraph()
  
      End sub 
  
  
   Public Function OnBegin(ByVal sender As Object, ByVal e As EventArgs, ByVal cb As AsyncCallback, ByVal extraData As Object) As IAsyncResult
  
      _dlgt = New AsyncTaskDelegate(AddressOf ReLoadSelectors)
      Dim result As IAsyncResult = _dlgt.BeginInvoke(cb, extraData)
  
      Return result
  End Function
  </code></pre>
  
  <p>`3) Load the data synchronous, and everything just works again, including the user-controls persisting their values, but just dead slow.</p>
  
  <p>I am going out of my mind with this one.  Works fine sync for everything, just not async.  Manged to get it to work on one page, where the user-control needs to do the async load call, but cannot make it work on another page, where the page has to do the async load call.  One type of task registration waits for the async data method to return, but the fully overloaded version using IAsyncResult does not.</p>
  
  <p>Please if anyone can spot where I have gone wrong, and put me out of my misery, I would be so grateful.</p>