ASP.NET 2.0 Asynchronous User Control Not Working

I am trying to get the user control to work asynchronously, but no matter what I do, it continues to work synchronously. I split it to a minimum as a test web application. This will be a 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 will be the page on which I place 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 is displayed without errors, but the trace at the bottom of the page shows that each control instance is processed synchronously. What am I doing wrong? Is there a configuration setting somewhere I'm missing?

+4
source share
2 answers

Looks like I can answer my own question. The user control should not call Page.ExecuteRegisteredAsyncTasks . By doing this, the control added an asynchronous task, ran it, and waited for it to complete.

Instead, each instance of the user control should only call Page.RegisterAsyncTask . After each management instance has completed this, the page automatically calls RegistereAsyncTask simultaneously execute all three registered asynchronous tasks.

So here is a new user control:

 <%@ Control Language="C#" %> <script runat="server"> SqlConnection m_oConnection; SqlCommand m_oCommand; void Page_Load(object sender, EventArgs e) { Trace.Warn(ID, "Page_Load - " + Thread.CurrentThread.GetHashCode().ToString()); string strDSN = ConfigurationManager.ConnectionStrings["DSN"].ConnectionString + ";async=true"; string strSQL = "waitfor delay '00:00:10'; select * from TEProcessedPerDay where Date > dateadd(day, -90, getutcdate()) order by Date asc"; 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)); } IAsyncResult BeginHandler(object src, EventArgs e, AsyncCallback cb, object state) { Trace.Warn(ID, "BeginHandler - " + Thread.CurrentThread.GetHashCode().ToString()); return m_oCommand.BeginExecuteReader(cb, state); } void EndHandler(IAsyncResult ar) { Trace.Warn(ID, "EndHandler - " + Thread.CurrentThread.GetHashCode().ToString()); GridView1.DataSource = m_oCommand.EndExecuteReader(ar); GridView1.DataBind(); m_oConnection.Close(); } void TimeoutHandler(IAsyncResult ar) { Trace.Warn(ID, "TimeoutHandler - " + Thread.CurrentThread.GetHashCode().ToString()); } </script> <asp:gridview id="GridView1" runat="server" /> 

And an immutable page that creates three instances of the control:

 <%@ page language="C#" async="true" trace="true" %> <%@ 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> 
+7
source

If I can add a little to the above post, we should not call ExecuteRegisteredAsyncTassk explicitly unless there is a good reason. after registering the async task, the ASP.NET structure will perform all these tasks immediately after the OnPrerender event of the OnPrerender life cycle.

An example of using ExecuteRegisteredAsyncTasks might be; Sometimes you may need to make sure that several asynchronous operations are completed before calling another async task. In this situation, you can use ExecuteRegisteredAsyncTasks .

+1
source

All Articles