まず、私がここで行っていることは完全に非現実的で、良い設計ではないように思えますが、8,000 行以上のマークアップを含むこの ASPX でパフォーマンスを向上させようとしています。このページの複雑さ (乱雑さは言うまでもありません) と期限が短いため、AJAX/JSON を使用するクライアント側バインディングを使用するようにページを書き直すことはできません。そのため、サーバー側バインディングを引き続き使用する必要があります。
私が取り組んでいるページには、約 13 の個別のセクションが含まれており、それぞれがデータベースから独自のエンティティをロードしています。現在、ページは最初にすべてのエンティティを同期的にロードするため、このページのロードに 5 秒以上かかる場合があることが想像できます。ここでの私の目標は、セクションが展開されたときにのみこれらのセクションをロードする簡単な修正を採用して、ユーザーが要求したセクションのみをロードすることで、パフォーマンスを向上させ、データベース リソースを節約することです。
以下のサンプル コードは、VB.NET の Web フォームに簡単に貼り付けることができるはずです。ページに名前を付けるだけですasyncupdatepanels.aspx
。
問題:
全体として、私のソリューションはかなりうまく機能しています。ではcmUpdate_Click
、Threading.Thread.Sleep(2000)
データベースへの呼び出しをシミュレートしてデータを取得します。いずれかのボタンをクリックすると、ボタンが 2 秒間停止し、適切な Panel の .Visible プロパティが True に設定されます。
この問題は、1 つのボタンをクリックし、最初のボタンの更新が完了する前に別のボタンをクリックすると発生します。たとえば、 をクリックしてShow Panel 1
からすばやくクリックShow Panel 2
すると、コードビハインドで両方のボタン クリックがトリガーされても、パネル 2 のみが表示されます。
たぶんasynchronous UpdatePanel
、ここで使用する用語は間違っています。とにかく、パネルが別々の非同期スレッドで実行されているかのように表示する方法を見つける必要があります。これらのボタンをほぼ同時にクリックして、両方のパネルを表示できるようにしたいと考えています。
各セクションでコントロールをバインドする方法に大きな変更を必要としない、私の問題に対する他の解決策がある場合は、ぜひ聞いてください。私が現在使用している方法はほとんどハックですが、最終的にこの全体を MVC/c# で書き直すまでは、今のところ機能します。
編集:プロダクション コードは、実際にはボタンの OnClientClick を使用して Javascript 関数を呼び出しません。代わりに、jQuery アコーディオンを使用します。サンプルコードをシンプルにしたかっただけです。現時点では、__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