I’m trying to get a user control working asynchronously, yet no matter what I do it continues to work synchronously. I’ve stripped it down to its bare minimum as a test web application. This would be the user control:
<%@ Control Language='C#' %> <script runat='server'> SqlConnection m_oConnection; SqlCommand m_oCommand; void Page_Load(object sender, EventArgs e) { Trace.Warn('Page_Load'); string strDSN = ConfigurationManager.ConnectionStrings['DSN'].ConnectionString + ';async=true'; string strSQL = 'waitfor delay '00:00:10'; select * from MyTable'; m_oConnection = new SqlConnection(strDSN); m_oCommand = new SqlCommand(strSQL, m_oConnection); m_oConnection.Open(); Page.RegisterAsyncTask(new PageAsyncTask(new BeginEventHandler(BeginHandler), new EndEventHandler(EndHandler), new EndEventHandler(TimeoutHandler), null, true)); Page.ExecuteRegisteredAsyncTasks(); } IAsyncResult BeginHandler(object src, EventArgs e, AsyncCallback cb, object state) { Trace.Warn('BeginHandler'); return m_oCommand.BeginExecuteReader(cb, state); } void EndHandler(IAsyncResult ar) { Trace.Warn('EndHandler'); GridView1.DataSource = m_oCommand.EndExecuteReader(ar); GridView1.DataBind(); m_oConnection.Close(); } void TimeoutHandler(IAsyncResult ar) { Trace.Warn('TimeoutHandler'); } </script> <asp:gridview id='GridView1' runat='server' />
And this would be the page in which I host the control three times:
<%@ page language='C#' trace='true' async='true' asynctimeout='60' %> <%@ register tagprefix='uc' tagname='mycontrol' src='~/MyControl.ascx' %> <html> <body> <form id='form1' runat='server'> <uc:mycontrol id='MyControl1' runat='server' /> <uc:mycontrol id='MyControl2' runat='server' /> <uc:mycontrol id='MyControl3' runat='server' /> </form> </body> </html>
The page gets displayed without errors, but the trace at the bottom of the page shows each control instance is processed synchronously. What am I doing wrong? Is there a configuration setting somewhere I’m missing?
Looks like I can answer my own question. The user control should not be calling
Page.ExecuteRegisteredAsyncTasks. By doing that, the control was adding the async task, running it, and waiting for it to complete.Instead, each instance of the user control should call only
Page.RegisterAsyncTask. After each control instance has done this the page automatically callsRegistereAsyncTaskrunning all three registered async tasks simultaniously.So here is the new user control:
And the unchanged page that creates three instances of the control: