Condividi tramite


Assegnazione della precedenza a un postback asincrono specifico

Aggiornamento: novembre 2007

Per impostazione predefinita, quando da una pagina hanno origine contemporaneamente più postback asincroni, il postback più recente ha la precedenza. In alcuni scenari potrebbe essere necessario assegnare la precedenza a un postback asincrono specifico e annullare gli altri.

In questa esercitazione si controllerà quale postback ha la precedenza. È possibile effettuare questa operazione creando un gestore eventi per l'evento initializeRequest della classe PageRequestManager. Per informazioni sulla sequenza di eventi generati nella classe PageRequestManager, vedere Utilizzo di eventi PageRequestManager.

Prerequisiti

Per implementare le procedure nell'ambiente di sviluppo in uso è necessario:

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

  • Sito Web ASP.NET con supporto AJAX.

Creazione di script per assegnare la precedenza a un elemento di postback specifico

Inizialmente verrà creato il codice ECMAScript (JavaScript) che gestisce il postback asincrono nel browser.

Per creare uno script che assegni la precedenza a un elemento di postback specifico

  1. Nel sito Web ASP.NET aggiungere un file JScript e denominarlo PostbackPrecedence.js.

  2. Aggiungere al file il seguente script:

    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();
    

    Lo script esegue le seguenti attività:

    • Definizione di un gestore per l'evento load della classe Sys.Application. Il gestore registra a sua volta un gestore denominato InitializeRequest per l'evento initializeRequest della classe PageRequestManager.

    • Definizione del gestore InitializeRequest per controllare se è in esecuzione un postback asincrono e determinare il nome dell'elemento che provoca il postback. Se l'elemento che provoca il postback è stato specificato come un elemento di postback esclusivo, ovvero un elemento che deve avere la precedenza, il nuovo postback viene annullato mediante l'impostazione delle proprietà cancel della classe InitializeRequestEventArgs.

    • Definizione di una funzione ActivateAlertDiv che attiva e disattiva la visibilità dell'elemento <div> utilizzato nella pagina per visualizzare messaggi.

Utilizzo dello script con un controllo UpdatePanel

In questa procedura si utilizzerà lo script creato in una pagina. Nella pagina è presente un pulsante il cui postback ha la precedenza rispetto al postback di un altro pulsante nella pagina.

Per creare una pagina in modo da assicurarsi che un postback abbia la precedenza rispetto a un postback

  1. Creare una nuova pagina Web ASP.NET a file singolo e passare alla visualizzazione Progettazione.

  2. Nella scheda Estensioni AJAX della casella degli strumenti fare doppio clic sul controllo ScriptManager per aggiungerlo alla pagina.

  3. Fare doppio clic sul controllo UpdatePanel per due volte per aggiungere due istanze del controllo alla pagina.

  4. In ogni controllo UpdatePanel, dalla scheda Standard della casella degli strumenti aggiungere un controllo Label e un controllo Button.

  5. Impostare il valore Text del controllo Label in entrambi i pannelli su Pannello inizialmente sottoposto a rendering.

  6. Fare doppio clic su ogni controllo Button per aggiungere un gestore per l'evento Click di ogni pulsante.

  7. Aggiungere il codice seguente per i gestori Click per creare artificialmente un ritardo e visualizzare l'ora corrente nel pannello in cui ha avuto origine il postback:

    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();        
    }
    
    Nota:

    Per questa esercitazione viene introdotto intenzionalmente un ritardo tramite i gestori per l'evento Click. Nella pratica il ritardo non viene introdotto, ma sarebbe il risultato di traffico del server o di codice server che richiede tempi di elaborazione lunghi, ad esempio una query di database a esecuzione prolungata.

  8. Passare alla visualizzazione Origine, quindi aggiungere il seguente blocco <style> nell'elemento <head> della pagina.

        <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>
    

    Le regole di stile consentono di definire l'altezza dell'elemento <div> di cui il controllo UpdatePanel esegue il rendering e dell'elemento <div> che avvisa l'utente quando viene annullato un postback.

  9. Aggiungere il markup seguente all'interno dell'elemento <form> presente nella pagina:

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

    Il markup consente di definire un elemento <div> che visualizzerà un messaggio quando un postback asincrono viene annullato perché un altro è già in corso.

  10. Passare alla visualizzazione Progettazione.

  11. Fare clic all'interno del primo controllo UpdatePanel, quindi dalla scheda Estensioni AJAX della casella degli strumenti aggiungere un controllo UpdateProgress.

  12. Fare clic all'interno del controllo UpdateProgress e digitare Aggiornamento di Panel1 ….

    In questo modo viene impostata la proprietà ProgressTemplate.

  13. Selezionare il controllo UpdateProgress, quindi nella finestra Proprietà impostare la proprietà AssociatedUpdatePanelID su UpdatePanel1.

    La pagina nella finestra di progettazione sarà simile a quella visualizzata nella figura seguente:

  14. Fare clic all'interno del secondo controllo UpdatePanel, quindi aggiungere un secondo controllo UpdateProgress.

  15. Fare clic all'interno del controllo UpdateProgress, quindi digitare Aggiornamento di Panel2 ….

    In questo modo viene impostata la proprietà ProgressTemplate.

  16. Selezionare il controllo UpdateProgress, quindi nella finestra Proprietà impostare la proprietà AssociatedUpdatePanelID su UpdatePanel2.

    La pagina nella finestra di progettazione sarà simile a quella visualizzata nella figura seguente:

  17. Selezionare il controllo ScriptManager.

  18. Nella finestra Proprietà selezionare la proprietà Scripts e fare clic sul pulsante con i puntini di sospensione (…) per visualizzare la finestra di dialogo Editor dell'insieme ScriptReference.

  19. Fare clic su Aggiungi per aggiungere un riferimento allo script.

  20. Impostare la proprietà Path del riferimento allo script su PostbackPrecedence.js, che rappresenta il file JavaScript creato precedentemente.

    Aggiungendo un riferimento allo script tramite l'insieme Scripts di ScriptManager si garantisce che lo script venga caricato dopo il caricamento della Microsoft AJAX Library.

  21. Scegliere OK per chiudere la finestra di dialogo Editor dell'insieme ScriptReference.

  22. Salvare le modifiche, quindi premere CTRL+F5 per visualizzare la pagina in un browser.

  23. Fare clic sul pulsante nel primo pannello, quindi fare clic sul pulsante nel secondo pannello.

    Verrà visualizzato un messaggio in cui è indicato che il nuovo postback è stato annullato. L'azione del pulsante nel primo pannello deve terminare prima che venga avviato un nuovo postback. Il file script fornisce la logica per applicare questo comportamento.

  24. Fare clic sul pulsante nel secondo pannello, quindi fare clic sul pulsante nel primo pannello.

    Il pulsante nel secondo pannello non ha la precedenza, poiché non è stato codificato a questo scopo nel file script. Non verrà quindi visualizzato alcun messaggio di avviso e tramite il pulsante nel primo pannello verrà avviato un nuovo postback. In base al comportamento predefinito dei postback asincroni, il postback più recente ha la precedenza.

    <%@ 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>
    

Verifica

In questa esercitazione viene descritto come consentire a un postback asincrono specifico di assumere la precedenza, ovvero terminare l'elaborazione, prima dell'avvio di un altro postback asincrono. La logica per l'applicazione di questo comportamento è presente in un file JavaScript incluso come un riferimento allo script per la pagina. Lo script può essere personalizzato in modo che l'azione di tutti i postback asincroni correnti venga completata prima che ne venga avviato uno nuovo. È tuttavia opportuno considerare con attenzione la progettazione quando si specifica quali postback avranno la precedenza.

Vedere anche

Concetti

Utilizzo di eventi PageRequestManager

Riferimenti

Classe Sys.WebForms.PageRequestManager

initializeRequest