2008-11-07 3 views
4

Я пытаюсь заставить пользовательский элемент управления работать асинхронно, но независимо от того, что я делаю, он продолжает работать синхронно. Я разделил его до минимума как тестовое веб-приложение. Это будет пользовательский элемент управления:ASP.NET 2.0 Асинхронный пользовательский контроль не работает

<%@ 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" /> 

И это будет страница, в которой я хозяйничать элемент управления три раза:

<%@ 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> 

страница получает отображаются без ошибок, но след в нижней части на странице показано, что каждый экземпляр управления обрабатывается синхронно. Что я делаю не так? Есть ли настройки конфигурации где-то я не хватает?

ответ

7

Похоже, я могу ответить на свой вопрос. Пользовательский контроль не должен звонить Page.ExecuteRegisteredAsyncTasks. Делая это, элемент управления добавлял задачу async, запускал ее и ожидал ее завершения.

Вместо этого каждый экземпляр пользовательского элемента управления должен вызывать только Page.RegisterAsyncTask. После того, как каждый экземпляр управления выполнил это, страница автоматически вызывает RegistereAsyncTask одновременным запуском всех трех зарегистрированных асинхронных задач.

Так вот новый пользовательский элемент управления:

<%@ 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" /> 

И неизменное страница, которая создает три экземпляра элемента управления:

<%@ 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> 
+1

mate .. mine все еще не работает, хотя не используется «ExecuteRegisteredAsyncTasks». Страница все еще ждет, пока пользовательский элемент управления завершится .. любые идеи? – user384080 2011-04-17 11:39:54

1

Если я могу добавить немного посте выше, мы не следует называть ExecuteRegisteredAsyncTassk явно, если нет веской причины. после регистрации async-задачи структура ASP.NET выполнит все эти задачи сразу после события OnPrerender жизненного цикла страницы.

Примером использования ExecuteRegisteredAsyncTasks может быть; Иногда вам может потребоваться выполнить несколько асинхронных операций перед вызовом другой задачи async. в подобной ситуации можно использовать ExecuteRegisteredAsyncTasks.

Смежные вопросы