Freigeben über


Einem bestimmten asynchronen Postback Vorrang gewähren

Aktualisiert: November 2007

Standardmäßig hat das zuletzt ausgelöste Postback den Vorrang, wenn von einer Seite mehrere asynchrone Postbacks zur gleichen Zeit ausgelöst werden. Möglicherweise möchten Sie in einigen Szenarien einem bestimmten asynchronen Postback den Vorrang gewähren und die anderen Postbacks abbrechen.

In diesem Lernprogramm steuern Sie, welches Postback Vorrang hat. Hierzu können Sie für das initializeRequest-Ereignis der PageRequestManager-Klasse einen Ereignishandler erstellen. Informationen zur Reihenfolge der Ereignisse, die in der PageRequestManager-Klasse ausgelöst werden, finden Sie unter Arbeiten mit PageRequestManager-Ereignissen.

Vorbereitungsmaßnahmen

Zur Implementierung dieser Prozeduren in Ihrer eigenen Entwicklungsumgebung ist Folgendes erforderlich:

  • Microsoft Visual Studio 2005 oder Microsoft Visual Web Developer Express Edition.

  • Eine AJAX-fähige ASP.NET-Website.

Erstellen eines Skripts, mit dem ein bestimmtes Postbackelement den Vorrang erhält

Erstellen Sie zunächst ECMAScript-(JavaScript-)Code, mit dem das asynchrone Postback im Browser verwaltet wird.

So erstellen Sie ein Skript, mit dem ein bestimmtes Postbackelement den Vorrang erhält

  1. Fügen Sie der ASP.NET-Website eine JScript-Datei hinzu, und nennen Sie diese PostbackPrecedence.js.

  2. Fügen Sie der Datei das folgende Skript hinzu:

    Sys.Application.add_load(ApplicationLoadHandler)
    function ApplicationLoadHandler(sender, args)
    {
        if (!Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack())
        {
          Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(InitializeRequest);
        }
    }
    
    var divElem = 'AlertDiv';
    var messageElem = 'AlertMessage';
    var exclusivePostBackElement = 'Button1';
    var lastPostBackElement;
    function InitializeRequest(sender, args)
    { 
        var prm = Sys.WebForms.PageRequestManager.getInstance();
        if (prm.get_isInAsyncPostBack() && 
            args.get_postBackElement().id === exclusivePostBackElement) 
        {
            if (lastPostBackElement === exclusivePostBackElement)
            {
              args.set_cancel(true);
              ActivateAlertDiv('visible', 'A previous postback is still executing. The new postback has been canceled.');
              setTimeout("ActivateAlertDiv('hidden','')", 1500);
            }
            else if (lastPostBackElement !== exclusivePostBackElement)
            {
              prm.abortPostBack();
            }
        }
        else if (prm.get_isInAsyncPostBack() && 
                 args.get_postBackElement().id !== exclusivePostBackElement)
        {
            if (lastPostBackElement === exclusivePostBackElement)
            {
                args.set_cancel(true);
                ActivateAlertDiv('visible', 'A previous postback is still executing. The new postback has been canceled.');
                setTimeout("ActivateAlertDiv('hidden','')", 1500);
            }       
        }
        lastPostBackElement = args.get_postBackElement().id;      
    }
    
    function ActivateAlertDiv(visString, msg)
    {
         var adiv = $get(divElem);
         var aspan = $get(messageElem);
         adiv.style.visibility = visString;
         aspan.innerHTML = msg;
    }
    if(typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();
    
    Sys.Application.add_load(ApplicationLoadHandler)
    function ApplicationLoadHandler(sender, args)
    {
        if (!Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack())
        {
          Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(InitializeRequest);
        }
    }
    
    var divElem = 'AlertDiv';
    var messageElem = 'AlertMessage';
    var exclusivePostBackElement = 'Button1';
    var lastPostBackElement;
    function InitializeRequest(sender, args)
    { 
        var prm = Sys.WebForms.PageRequestManager.getInstance();
        if (prm.get_isInAsyncPostBack() && 
            args.get_postBackElement().id === exclusivePostBackElement) 
        {
            if (lastPostBackElement === exclusivePostBackElement)
            {
              args.set_cancel(true);
              ActivateAlertDiv('visible', 'A previous postback is still executing. The new postback has been canceled.');
              setTimeout("ActivateAlertDiv('hidden','')", 1500);
            }
            else if (lastPostBackElement !== exclusivePostBackElement)
            {
              prm.abortPostBack();
            }
        }
        else if (prm.get_isInAsyncPostBack() && 
                 args.get_postBackElement().id !== exclusivePostBackElement)
        {
            if (lastPostBackElement === exclusivePostBackElement)
            {
                args.set_cancel(true);
                ActivateAlertDiv('visible', 'A previous postback is still executing. The new postback has been canceled.');
                setTimeout("ActivateAlertDiv('hidden','')", 1500);
            }       
        }
        lastPostBackElement = args.get_postBackElement().id;      
    }
    
    function ActivateAlertDiv(visString, msg)
    {
         var adiv = $get(divElem);
         var aspan = $get(messageElem);
         adiv.style.visibility = visString;
         aspan.innerHTML = msg;
    }
    if(typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();
    

    Dieses Skript führt die folgenden Aufgaben aus:

    • Definiert einen Handler für das load-Ereignis der Sys.Application-Klasse. Dieser Handler wiederum registriert den Handler InitializeRequest für das initializeRequest-Ereignis der PageRequestManager-Klasse.

    • Definiert den InitializeRequest-Handler zum überprüfen, ob derzeit ein asynchrones Postback ausgeführt wird. Wenn dies der Fall ist, wird der Name des Elements abgerufen, von dem das Postback ausgelöst wurde. Wenn Sie das Element, von dem das Postback ausgelöst wurde, als ein exklusives Postbackelement festgelegt haben (ein Element, das den Vorrang hat), wird das neue Postback abgebrochen, indem die cancel-Eigenschaft der InitializeRequestEventArgs-Klasse festgelegt wird.

    • Definiert zum Anzeigen von Meldungen eine ActivateAlertDiv-Funktion, die das Ein- bzw. Ausschalten der Sichtbarkeit eines <div>-Elements auf der Seite steuert.

Verwenden des Skripts mit einem UpdatePanel-Steuerelement

In diesem Verfahren wird das Skript verwendet, das Sie für die Seite erstellt haben. Die Seite enthält eine Schaltfläche, deren Postback Vorrang gegenüber dem Postback einer anderen Schaltfläche auf der Seite hat.

So erstellen Sie eine Seite, die sicherstellt, dass ein Postback gegenüber einem anderen Postback Vorrang hat

  1. Erstellen Sie eine neue ASP.NET-Webseite als einzelne Datei, und wechseln Sie in die Entwurfsansicht.

  2. Doppelklicken Sie auf der Registerkarte AJAX-Erweiterungen der Toolbox auf das ScriptManager-Steuerelement, um es der Seite hinzuzufügen.

  3. Doppelklicken Sie zweimal auf das UpdatePanel-Steuerelement, um der Seite zwei Instanzen des Steuerelements hinzuzufügen.

  4. Fügen Sie jedem UpdatePanel-Steuerelement auf der Registerkarte Standard der Toolbox ein Label-Steuerelement und ein Button-Steuerelement hinzu.

  5. Legen Sie den Text-Wert des Label-Steuerelements in beiden Bereichen auf Bereich gerendert fest.

  6. Doppelklicken Sie auf jedes Button-Steuerelement, um jeder Schaltfläche einen Handler für das Click-Ereignis hinzuzufügen.

  7. Fügen Sie den Click-Handlern folgenden Code hinzu, mit dem eine künstliche Verzögerung erzeugt und anschließend die aktuelle Uhrzeit in dem Bereich angezeigt wird, von dem der Postback stammt:

    Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs)
        System.Threading.Thread.Sleep(4000)
        Label1.Text = "Last update from server " & DateTime.Now.ToString()
    End Sub
    
    Protected Sub Button2_Click(ByVal sender As Object, ByVal e As EventArgs)
        System.Threading.Thread.Sleep(1000)
        Label2.Text = "Last update from server " & DateTime.Now.ToString()
    End Sub
    
    protected void Button1_Click(object sender, EventArgs e)
    {
        System.Threading.Thread.Sleep(4000);
        Label1.Text = "Last update from server " + DateTime.Now.ToString();        
    }
    
    protected void Button2_Click(object sender, EventArgs e)
    {
        System.Threading.Thread.Sleep(1000);
        Label2.Text = "Last update from server " + DateTime.Now.ToString();        
    }
    
    Hinweis:

    In diesem Lernprogramm erzeugen die Handler des Click-Ereignisses absichtlich eine Verzögerung. In der Praxis würden Sie keine Verzögerung erzeugen. Eine Verzögerung wäre vielmehr die Folge von zu hohem Datenverkehr auf dem Server oder von Servercode, der eine lange Verarbeitungszeit erfordert (z. B. eine Datenbankabfrage mit einer langen Laufzeit).

  8. Wechseln Sie in die Quellansicht, und fügen Sie den folgenden <style>-Block dem <head>-Element auf der Seite hinzu:

        <style type="text/css">
        body {
            font-family: Tahoma;
        }
        #UpdatePanel1, #UpdatePanel2 {
          width: 400px;
          height: 100px;
          border: solid 1px gray;
        }
        div.MessageStyle {
          background-color: #FFC080;
          top: 95%;
          left: 1%;
          height: 20px;
          width: 600px;
          position: absolute;
          visibility: hidden;
        }
        </style>
    
        <style type="text/css">
        body {
            font-family: Tahoma;
        }
        #UpdatePanel1, #UpdatePanel2 {
          width: 400px;
          height: 100px;
          border: solid 1px gray;
        }
        div.MessageStyle {
          background-color: #FFC080;
          top: 95%;
          left: 1%;
          height: 20px;
          width: 600px;
          position: absolute;
          visibility: hidden;
        }
        </style>
    

    Die Stilregeln definieren die Größe des <div>-Elements, das vom UpdatePanel-Steuerelement gerendert wird, und die Größe des <div>-Elements, das den Benutzer auf das Abbrechen eines Postbacks hinweist.

  9. Fügen Sie das folgende Markup im <form>-Element der Seite hinzu:

    <div id="AlertDiv" class="MessageStyle">
    <span id="AlertMessage"></span>
    </div>
    
    <div id="AlertDiv" class="MessageStyle">
    <span id="AlertMessage"></span>
    </div>
    

    In diesem Markup wird ein <div>-Element definiert, durch das eine Meldung angezeigt wird, wenn ein asynchrones Postback aufgrund eines bereits in Verarbeitung befindlichen Postbacks abgebrochen wird.

  10. Wechseln Sie in die Entwurfsansicht.

  11. Klicken Sie in das erste UpdatePanel-Steuerelement, und fügen Sie diesem anschließend aus der Registerkarte AJAX-Erweiterungen der Toolbox das UpdateProgress-Steuerelement hinzu.

  12. Klicken Sie in das UpdateProgress-Steuerelement, und geben Sie Folgendes ein: Panel1 wird aktualisiert ….

    Hierdurch wird die ProgressTemplate -Eigenschaft festgelegt.

  13. Wählen Sie das UpdateProgress-Steuerelement aus, und legen Sie anschließend im Eigenschaftenfenster die AssociatedUpdatePanelID-Eigenschaft auf Aktualisierung Panel1 fest.

    Die Seite im Designer sollte der folgenden Abbildung entsprechen:

  14. Klicken Sie in das zweite UpdatePanel-Steuerelement, und fügen Sie ein zweites UpdateProgress-Steuerelement hinzu.

  15. Klicken Sie in das UpdateProgress-Steuerelement, und geben Sie Folgendes ein: Panel2 wird aktualisiert ….

    Hierdurch wird die ProgressTemplate -Eigenschaft festgelegt.

  16. Wählen Sie das UpdateProgress-Steuerelement aus, und legen Sie anschließend im Eigenschaftenfenster die AssociatedUpdatePanelID-Eigenschaft auf Aktualisierung Panel2 fest.

    Die Seite im Designer sollte der folgenden Abbildung entsprechen:

  17. Wählen Sie das ScriptManager-Steuerelement aus.

  18. Wählen Sie im Eigenschaftenfenster die Scripts-Eigenschaft aus, und klicken Sie auf die Auslassungszeichen (…), um das Dialogfeld ScriptReference-Auflistungs-Editor anzuzeigen.

  19. Klicken Sie auf Hinzufügen, um einen Skriptverweis hinzuzufügen.

  20. Legen Sie die Pfad-Eigenschaft des Skriptverweises auf die zuvor erstellte JavaScript-Datei PostbackPrecedence.js fest.

    Durch das Hinzufügen eines Skriptverweises mithilfe der Scripts-Auflistung von ScriptManager wird sichergestellt, dass das Skript erst nach dem Laden von Microsoft AJAX Library geladen wird.

  21. Klicken Sie zum Schließen des Dialogfelds ScriptReference-Auflistungs-Editor auf OK.

  22. Speichern Sie die Änderungen. Drücken Sie anschließend STRG+F5, um die Seite in einem Browser anzuzeigen.

  23. Klicken Sie auf die Schaltfläche im ersten Bereich und anschließend auf die Schaltfläche im zweiten Bereich.

    Es wird eine Meldung angezeigt, dass das neue Postback abgebrochen wurde. Der Schaltflächenvorgang im ersten Bereich muss abgeschlossen sein, bevor ein neues Postback initiiert wird. Die Skriptdatei stellt die Programmlogik zum Erzwingen dieses Verhaltens bereit.

  24. Klicken Sie auf die Schaltfläche im zweiten Bereich und anschließend auf die Schaltfläche im ersten Bereich.

    Die Schaltfläche im zweiten Bereich hat keinen Vorrang, da dies in der Skriptdatei nicht codiert wurde. Daher wird durch die Schaltfläche im ersten Bereich ohne Anzeige einer Warnmeldung ein neues Postback ausgelöst. Das ist das Standardverhalten von asynchronen Postbacks – das zuletzt ausgelöste Postback hat Vorrang.

    <%@ Page Language="VB" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <script >
        Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs)
            System.Threading.Thread.Sleep(4000)
            Label1.Text = "Last update from server " & DateTime.Now.ToString()
        End Sub
    
        Protected Sub Button2_Click(ByVal sender As Object, ByVal e As EventArgs)
            System.Threading.Thread.Sleep(1000)
            Label2.Text = "Last update from server " & DateTime.Now.ToString()
        End Sub
    </script>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head id="Head1" >
        <title>Postback Precedence Example</title>
        <style type="text/css">
        body {
            font-family: Tahoma;
        }
        #UpdatePanel1, #UpdatePanel2 {
          width: 400px;
          height: 100px;
          border: solid 1px gray;
        }
        div.MessageStyle {
          background-color: #FFC080;
          top: 95%;
          left: 1%;
          height: 20px;
          width: 600px;
          position: absolute;
          visibility: hidden;
        }
        </style>
    </head>
    <body>
        <form id="form1" >
            <div>
                <asp:ScriptManager ID="ScriptManager1" >
                <Scripts>
                <asp:ScriptReference Path="PostBackPrecedence.js" />
                </Scripts>
                </asp:ScriptManager>
                <asp:UpdatePanel  ID="UpdatePanel1" UpdateMode="Conditional" runat="Server" >
                    <ContentTemplate>
                    <strong>UpdatePanel 1</strong><br />
    
                    This postback takes precedence.<br />
                    <asp:Label ID="Label1" >Panel initially rendered.</asp:Label><br />
                    <asp:Button ID="Button1"  Text="Button" OnClick="Button1_Click" />&nbsp;
                    <asp:UpdateProgress ID="UpdateProgress1"  AssociatedUpdatePanelID="UpdatePanel1">
                    <ProgressTemplate>
                    Panel1 updating...
                    </ProgressTemplate>
                    </asp:UpdateProgress>
                    </ContentTemplate>
                </asp:UpdatePanel>
                <asp:UpdatePanel  ID="UpdatePanel2" UpdateMode="Conditional" runat="Server" >
                    <ContentTemplate>
                    <strong>UpdatePanel 2</strong><br />
                    <asp:Label ID="Label2" >Panel initially rendered.</asp:Label><br />
                    <asp:Button ID="Button2"  Text="Button" OnClick="Button2_Click" />
                    <asp:UpdateProgress ID="UpdateProgress2"  AssociatedUpdatePanelID="UpdatePanel2">
                    <ProgressTemplate>
                    Panel2 updating...
                    </ProgressTemplate>
                    </asp:UpdateProgress>
                    </ContentTemplate>
                </asp:UpdatePanel>
               <div id="AlertDiv" class="MessageStyle">
               <span id="AlertMessage"></span>
               </div>
            </div>
        </form>
    </body>
    </html>
    
    <%@ Page Language="C#" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <script >
        protected void Button1_Click(object sender, EventArgs e)
        {
            System.Threading.Thread.Sleep(4000);
            Label1.Text = "Last update from server " + DateTime.Now.ToString();        
        }
    
        protected void Button2_Click(object sender, EventArgs e)
        {
            System.Threading.Thread.Sleep(1000);
            Label2.Text = "Last update from server " + DateTime.Now.ToString();        
        }
    </script>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head id="Head1" >
        <title>Postback Precedence Example</title>
        <style type="text/css">
        body {
            font-family: Tahoma;
        }
        #UpdatePanel1, #UpdatePanel2 {
          width: 400px;
          height: 100px;
          border: solid 1px gray;
        }
        div.MessageStyle {
          background-color: #FFC080;
          top: 95%;
          left: 1%;
          height: 20px;
          width: 600px;
          position: absolute;
          visibility: hidden;
        }
        </style>
    </head>
    <body>
        <form id="form1" >
            <div>
                <asp:ScriptManager ID="ScriptManager1" >
                <Scripts>
                <asp:ScriptReference Path="PostBackPrecedence.js" />
                </Scripts>
                </asp:ScriptManager>
                <asp:UpdatePanel  ID="UpdatePanel1" UpdateMode="Conditional" runat="Server" >
                    <ContentTemplate>
                    <strong>UpdatePanel 1</strong><br />
    
                    This postback takes precedence.<br />
                    <asp:Label ID="Label1" >Panel initially rendered.</asp:Label><br />
                    <asp:Button ID="Button1"  Text="Button" OnClick="Button1_Click" />&nbsp;
                    <asp:UpdateProgress ID="UpdateProgress1"  AssociatedUpdatePanelID="UpdatePanel1">
                    <ProgressTemplate>
                    Panel1 updating...
                    </ProgressTemplate>
                    </asp:UpdateProgress>
                    </ContentTemplate>
                </asp:UpdatePanel>
                <asp:UpdatePanel  ID="UpdatePanel2" UpdateMode="Conditional" runat="Server" >
                    <ContentTemplate>
                    <strong>UpdatePanel 2</strong><br />
                    <asp:Label ID="Label2" >Panel initially rendered.</asp:Label><br />
                    <asp:Button ID="Button2"  Text="Button" OnClick="Button2_Click" />
                    <asp:UpdateProgress ID="UpdateProgress2"  AssociatedUpdatePanelID="UpdatePanel2">
                    <ProgressTemplate>
                    Panel2 updating...
                    </ProgressTemplate>
                    </asp:UpdateProgress>
                    </ContentTemplate>
                </asp:UpdatePanel>
               <div id="AlertDiv" class="MessageStyle">
               <span id="AlertMessage"></span>
               </div>
            </div>
        </form>
    </body>
    </html>
    

Zusammenfassung

In diesem Lernprogramm wird veranschaulicht, wie ein bestimmtes asynchrones Postback Vorrang erhält (d. h. die Verarbeitung wird abgeschlossen), bevor ein anderes asynchrones Postback gestartet wird. Die Programmlogik zum Erzwingen dieses Verhaltens befindet sich in einer JavaScript-Datei, die als Skriptverweis auf der Seite enthalten ist. Dieses Skript kann so angepasst werden, dass alle aktuellen asynchronen Postbacks abgeschlossen werden müssen, bevor ein neues Postback gestartet wird. Sie sollten Ihren Entwurf sorgfältig prüfen, wenn Sie festlegen, welche Postbacks Vorrang haben.

Siehe auch

Konzepte

Arbeiten mit PageRequestManager-Ereignissen

Referenz

Sys.WebForms.PageRequestManager-Klasse

initializeRequest