首先,我知道我在這裏做什麼看起來完全不切實際,並不是很好的設計,但我試圖提高包含8000多行標記的ASPX的性能。由於這個頁面的複雜性(更不用說混亂)和簡短的截止日期,重寫它以使用客戶端與AJAX/JSON綁定不是一個選項,所以我必須繼續使用serverside綁定。ASP.NET WebForms:異步UpdatePanel?
我正在處理的頁面包含大約13個單獨的部分,每個部分都從數據庫加載它自己的實體。現在,頁面最初同步加載所有實體,因此您可以想象此頁面有時可能需要5秒或更長時間才能加載。我的目標是採用一種快速修復方法,只有在部分展開後才能加載這些部分,以便僅加載用戶請求的部分,從而提高性能並節省數據庫資源。
下面的示例代碼應該很容易,如果你有興趣嘗試了這一點爲自己粘貼到一個VB.NET的WebForm。只需命名頁面asyncupdatepanels.aspx
。
問題: 總的來說,我的解決方案工作得很好。在cmUpdate_Click
中,我使用Threading.Thread.Sleep(2000)
來模擬對數據庫的調用以檢索數據。當您單擊其中一個按鈕時,它會暫停2秒,然後將適當的Panel的.Visible屬性設置爲True。
當您單擊一個按鈕,然後在第一個完成更新之前單擊另一個按鈕時,會出現此問題。例如,如果單擊Show Panel 1
,然後快速單擊Show Panel 2
,即使在代碼隱藏中觸發了兩個按鈕點擊,也只有面板2顯示。
也許asynchronous UpdatePanel
是錯誤的用語用在這裏。無論如何,我需要找到一種方法來顯示面板,就好像它們在單獨的異步線程中執行一樣。我希望能夠在幾乎同一時間點擊這些按鈕並顯示兩個面板。
如果任何人有任何其他的解決方案,我的問題,這將不需要對我綁定控件中的每個部分的方式發生重大變化,我很樂意聽到它。我現在使用的方法幾乎是一種黑客攻擊,但它現在可以工作,直到我們最終在MVC/c#中重寫這整個事情。
編輯:生產代碼實際上並不使用按鈕的OnClientClick調用Javascript函數。相反,它使用jQuery手風琴。我只是想簡化示例代碼。目前,無論最終如何調用__doPostBack("<%=cmUpdate.ClientID %>", ButtonId);
,都將注意力放在__doPostBack("<%=cmUpdate.ClientID %>", ButtonId);
上。
ASPX
<%@ Page Language="vb" AutoEventWireup="false" EnableEventValidation="false" CodeBehind="asyncupdatepanels.aspx.vb" Inherits="JsonJqueryDevex.asyncupdatepanels" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script language="javascript" type="text/javascript">
function UpdateIt(ButtonId) {
__doPostBack("<%=cmUpdate.ClientID %>", ButtonId);
return false;
}
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div>
<asp:Button ID="cmShow1" Text="Show Panel 1" ClientIDMode="Static" OnClientClick="javascript:return UpdateIt(this.id);" runat="server" />
<asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:Panel ID="pnl1" Visible="false" runat="server">
Panel 1 content
</asp:Panel>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="cmUpdate" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
<asp:Button ID="cmShow2" Text="Show Panel 2" ClientIDMode="Static" OnClientClick="javascript:return UpdateIt(this.id);" runat="server" />
<asp:UpdatePanel ID="UpdatePanel2" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:Panel ID="pnl2" Visible="false" runat="server">
Panel 2 content
</asp:Panel>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="cmUpdate" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
<div style="display: none">
<asp:UpdatePanel UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:Button ID="cmUpdate" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
</div>
</form>
</body>
</html>
代碼隱藏:
Public Class asyncupdatepanels
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
End Sub
Private Sub cmUpdate_Click(sender As Object, e As System.EventArgs) Handles cmUpdate.Click
Dim Param As String = Request("__EVENTARGUMENT")
Threading.Thread.Sleep(2000)
Select Case Param
Case "cmShow1"
pnl1.Visible = True
Case "cmShow2"
pnl2.Visible = True
End Select
End Sub
End Class
爲什麼不顯示更新進度欄,直到UpdatePanel中的內容被加載。否則,最好遵循延遲加載方法來填充內容。即動態構建這些元素 –