0

First off, I know that what I am doing here seems entirely impractical and not good design, but I am trying to increase performance in this ASPX that contains 8,000+ lines of markup. Because of the complexity of this page (not to mention messiness) and short deadline, rewriting it to use clientside binding with AJAX/JSON is just not an option, so I have to continue to use serverside binding.

The page I am working on contains around 13 individual sections, each one loading its own entity from the database. Right now, the page initially loads ALL entities synchronously, so you can imagine that this page can sometimes take 5 seconds or longer to load. My goal here is to employ a quick fix that will load these sections only when the section is expanded so that we load only the sections that are requested by the user, thus increasing performance and conserving database resources.

The sample code below should be easy to paste right into a VB.NET WebForm if you're interested in trying this out for yourself. Just name the page asyncupdatepanels.aspx.

The problem: Overall, my solution is working fairly well. In cmUpdate_Click, I use Threading.Thread.Sleep(2000) to simulate a call to the database to retrieve data. When you click one of the buttons, it pauses for 2 seconds and then sets the appropriate Panel's .Visible property to True.

The issue occurs when you click one button and then click the the other before the first one is finished updating. For example, if you click Show Panel 1 then quickly click Show Panel 2, only Panel 2 shows even though both button clicks are triggered in the codebehind.

Maybe asynchronous UpdatePanel is the wrong term to use here. Regardless, I need to find a way to show the panels as if they were executed in separate asyncronous threads. I want to be able to click these buttons pretty much near the same time and have both panels show.

If anyone has any other solutions to my problem that will not require major changes to the way I bind controls in each section, I'd love to hear it. The method I am using now is pretty much a hack, but it will work for now until we eventually rewrite this whole thing in MVC/c#.

Edit: The production code doesn't actually call a Javascript function by use of a button's OnClientClick. Instead, it uses a jQuery accordion. I just wanted to keep the sample code simple. For now, focus on __doPostBack("<%=cmUpdate.ClientID %>", ButtonId); regardless of how it's ultimately called.

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>

Codebehind:

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
4

2 回答 2

0

I would do an AJAX call to your server-side in the page_load event of the page where your updated panel is. You would then call the Update method of your update panel when your processing is done.

You won't have to wait for the processing to be done to do whatever you want to do meanwhile.

Javascript(with jQuery):

function ajaxCall() {
    $.ajax({
        url: "YourPage.aspx"
    });
}

You can process your AJAX call in the Page_Load in your .NET.

I know that you said using AJAX wouldn't be a good option, but this is fairly short and simple.

于 2012-09-11T14:12:23.337 回答
0

如何在点击时禁用相应的按钮?

说,

function UpdateIt(ButtonId) {
           $('#<%=cmShow1.ClientID %>').attr('disabled', true);
           $('#<%=cmShow2.ClientID %>').attr('disabled', true);
            __doPostBack("<%=cmUpdate.ClientID %>", ButtonId);
            return false;
        }

然后,在您的代码中,在睡眠之后,再次启用它们(cmShow1.Enabled = true / cmShow2.Enabled = true) - UpdatePanel 调用将处理其余部分。

于 2012-09-11T14:10:03.497 回答