2011-07-20 31 views
1

我很難過。我試圖顯示一個進度條,而我的網站執行查詢。查詢需要4-6分鐘。我的進度條從數據庫中獲得它的價值,Oracle有一個內置的查詢來爲進度條提供值。我正在使用EssentialObjects' ProgressBar。基本上,我只是設置 「值」 爲1,100如何在異步回發期間更新頁面?

這裏的整數是我的代碼的簡化版本:

頁:

<asp:UpdatePanel ID="upQuery" runat="server"> 
    <ContentTemplate> 
     <asp:Button ID="btnExecute" runat="server" OnClick="btnExecute_Click" /> 
    </ContentTemplate> 
</asp:UpdatePanel> 
<asp:UpdatePanel ID="upProgress" runat="server"> 
    <ContentTemplate> 
     <asp:Timer ID="tmr" runat="server" Enabled="false" 
        OnTick="tmr_Tick" Interval="3000"></asp:Timer> 
     <eo:ProgressBar ID="pbr" runat="server" ></eo:ProgressBar> 
    </ContentTemplate> 
</asp:UpdatePanel> 

代碼:

protected void btnExecute_Click(object sender, EventArgs e) { 
     tmr.Enabled = true; 
     ExecuteLongQuery(); 
} 

protected void tmr_Tick(object sender, EventArgs e) { 
     pbr.Value = GetProgress(); 
} 

基本上,當我單擊btnExecute時,計時器不會啓動,直到回發完成,使進度條從不顯示。我嘗試了一個回調,不知道我是否做得對,但頁面在回發期間不會顯示結果。如何在頁面處於異步回發時獲取定時器(或任何其他內容)?

+1

您應該提供更多關於線程和更多代碼的信息。這個想法是,你要麼訂閱你的查詢/類的ProgressChanged事件,要麼訂閱該類的內部,調用用戶界面,但這兩種方式,以幫助我們需要看到更多的代碼。 –

+0

這是一個網頁,而不是Windows窗體。沒有ProgressChanged事件,因爲我正在使用自定義控件。我不知道還有什麼我需要提供.. – tedski

+1

ExecuteLongQuery()的代碼將有所幫助... –

回答

3

直到回發完成後,您啓用計時器的事實才會傳遞給客戶端。這就是它的工作原理。在服務器上執行代碼不會對客戶端產生直接影響。如果您在將響應發送給客戶端之前等待ExecuteLongQuery()完成,那麼您將永遠看不到計時器。

最好的辦法可能是在服務器上的一個單獨的線程中運行ExecuteLongQuery(),允許回發完成並啓動計時器。

我建議閱讀ASP.Net頁面生命週期 - this看起來是一個很好的開始。

+0

我想我的印象是使用UpdatePanel會啓動另一個線程,但我想這不是那麼容易。我會研究線程。有沒有一個你知道的很好的教程? – tedski

+0

啊,沒有。 UpdatePanel只是做了一個回傳,只重新加載頁面的一部分。直到事件處理程序中的所有代碼都執行完畢,它纔會返回給客戶端。我沒有使用.NET的線程的經驗,但我相信你需要使用ASP.Net支持的工作線程。谷歌周圍,你應該能夠很容易地找到一個教程。祝你好運! :) –

+0

哇,這真的很容易。我只是使用[this](http://www.sitepoint.com/threading-asp-net/)教程。謝謝! – tedski

5

我發現這個,它適用於我。你可以根據你的需要改變它。它適用於每一頁回發,如果你想限制它,然後改變你的需求的代碼。

<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head id="Head1" runat="server"> 
     <title></title> 
     <style type="text/css"> 
      .modalPopup 
      { 
       background-color: #696969; 
       filter: alpha(opacity=40); 
       opacity: 0.7; 
       xindex: -1; 
      } 
     </style> 
    </head> 
    <body> 
     <form id="form2" runat="server"> 
       <asp:ScriptManager ID="ScriptManager2" runat="server" /> 
       <script type="text/javascript"> 
        var prm = Sys.WebForms.PageRequestManager.getInstance(); 
        //Raised before processing of an asynchronous postback starts and the postback request is sent to the server. 
        prm.add_beginRequest(BeginRequestHandler); 
        // Raised after an asynchronous postback is finished and control has been returned to the browser. 
        prm.add_endRequest(EndRequestHandler); 
        function BeginRequestHandler(sender, args) 
        { 
         //Shows the modal popup - the update progress 
         var popup = $find('<%= modalPopup.ClientID %>'); 
         if (popup != null) 
         { 
          popup.show(); 
         } 
        } 

        function EndRequestHandler(sender, args) 
        { 
         //Hide the modal popup - the update progress 
         var popup = $find('<%= modalPopup.ClientID %>'); 
         if (popup != null) 
         { 
          popup.hide(); 
         } 
        } 
       </script> 
       <div> 
        <asp:UpdateProgress ID="UpdateProgress1" runat="server"> 
         <ProgressTemplate> 
          <asp:Image ID="Image1" ImageUrl="waiting.gif" AlternateText="Processing" runat="server" /> 
         </ProgressTemplate> 
        </asp:UpdateProgress> 
        <ajaxtoolkit:modalpopupextender id="modalPopup" runat="server" targetcontrolid="UpdateProgress" popupcontrolid="UpdateProgress" backgroundcssclass="modalPopup" /> 
        <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional"> 
         <ContentTemplate> 
          <asp:Button ID="Button1" runat="server" Text="Submit" OnClick="btnSubmit_Click" /> 
         </ContentTemplate> 
        </asp:UpdatePanel> 
      </div> 
     </form> 
    </body> 
</html>