2009-12-04 9 views
9

Ich versuche, Daten in Update-Panels auf einer Website asynchron anzuzeigen, wo die Datenabfrage-Aufgaben unterschiedliche Zeiten dauern. Ich möchte jedes Panel aktualisieren, um die Daten auf der Seite nach Abschluss jeder Aufgabe anzuzeigen.ASP.Net: Asynchrones Update-Panel Laden mit zwei Update-Panels

Egal, was ich versuche, ändern alle Update-Panels ihren Inhalt, nachdem die letzte Aufgabe abgeschlossen ist.

Zum Beispiel:

Ich habe zwei Aufgaben:

  • Eines, das ein Etikett in UpdatePanel1 nach 5 Sekunden
  • Eines, das ein Etikett in UpdatePanel2 zu aktualisieren versucht, zu aktualisieren versucht nach 10 Sekunden

Das erwartete Ergebnis ist zu Hav Das Etikett in UpdatePanel1 ändert sich nur nach 5 Sekunden. Beide Update-Panels werden jedoch gleichzeitig um 10 Sekunden aktualisiert.

Beide Update-Panels sind auf updatemode = "Conditional" gesetzt und sie werden aufgefordert, Postback von Client-Javascript. Unten finden Sie eine vollständige Auflistung des obigen Beispiels. hier

Was bin ich? Wie bekomme ich ein Update-Panel geladen, und das andere, beide Aufgaben asynchron ausgeführt werden?

Danke,

TM

ASPX:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" 
    Inherits="_Default"%> 

<!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> 
</head> 
<body onload="partialPostback();"> 
    <script language="JavaScript" type="text/javascript"> 

    function partialPostback() { 
     __doPostBack('UpdatePanel1', ''); 
     __doPostBack('UpdatePanel2', ''); 
    } 
    </script> 

    <form id="form1" runat="server"> 
     <asp:ScriptManager ID="ScriptManager1" runat="server"/> 

     5 sec: 
     <asp:UpdatePanel ID="UpdatePanel1" runat="server" 
     UpdateMode="Conditional" OnLoad="UpdatePanel1_Load"> 
      <ContentTemplate> 
       <asp:Label ID="Label2" runat="server" Text="Label"/><br /> 
      </ContentTemplate> 
     </asp:UpdatePanel><br /> 

     10 sec: 
     <asp:UpdatePanel ID="UpdatePanel2" runat="server" 
     UpdateMode="Conditional" OnLoad="UpdatePanel2_Load"> 
      <ContentTemplate> 
       <asp:Label ID="Label1" runat="server" Text="Label"/><br /> 
      </ContentTemplate> 
     </asp:UpdatePanel> 
    </form> 
</body> 
</html> 

C#:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using System.Threading; 

public partial class _Default : System.Web.UI.Page 
{ 
    Thread t1; 
    Thread t2; 

    protected override void OnPreRender(EventArgs e) 
    { 
     if (t1 != null) 
     { t1.Join(); } 

     if (t2 != null) 
     { t2.Join(); } 

     base.OnPreRender(e); 
    } 

    protected void Page_Load(object sender, EventArgs e) 
    { } 

    protected void UpdatePanel1_Load(object sender, EventArgs e) 
    { 
     if (IsPostBack) 
     { 
      ThreadStart tstart = new ThreadStart(DoWork1); 
      t1 = new Thread(tstart); 
      t1.IsBackground = true; 
      t1.Start(); 
     } 
    } 

    protected void UpdatePanel2_Load(object sender, EventArgs e) 
    { 
     if (IsPostBack) 
     { 
      ThreadStart tstart = new ThreadStart(DoWork2); 
      t2 = new Thread(tstart); 
      t2.IsBackground = true; 
      t2.Start(); 
     } 
    } 

    private void DoWork1() 
    { 
     Thread.Sleep(5000); 
     this.Label2.Text = "Done in 5 sec!"; 
     this.UpdatePanel1.Update(); 
    } 

    private void DoWork2() 
    { 
     Thread.Sleep(10000); 
     this.Label1.Text = "Done in 10 sec!"; 
     this.UpdatePanel2.Update(); 
    } 
} 

Antwort

0

Ich vermute, dass man das nicht nennen als asynchron, wie Sie denken b/c der Thread verbindet. Es sieht so aus, als würden Sie Block OnPrender blockieren, bis Thread 2 beendet wird. Da sowohl 1 als auch 2 von derselben Methode aufgerufen werden, sind Sie blockiert, bis beide fertig sind. Wenn Sie ein paar Schreibstriche einwerfen, um zu sehen, wann die Dinge aufgerufen werden, wird es vielleicht etwas einfacher zu sehen, was passiert.

Ich vermute auch, dass der Text auf 1 wird nicht wirklich aktualisiert, bis prerender vollständig ist, was ich weiß. Traditionelles ASP.NET, nichts wird zurück an den Client gesendet, bis nach Prerender abgeschlossen ist. Aber ich weiß nicht viel über Update-Panel, so könnte ich Junk darüber reden und antizipiert werden markiert ...

0

Die Joins in Ihrem Pre-Render-Handler blockieren das Rendern von zurück zum Client . Statt dessen, was Sie haben, wie ich vermute, dass Sie so etwas wie dies stattdessen tun könnte:

if (t1 != null) { 
    t1.join(); 
} else if (t2 != null) { 
    t2.join(); 
} 

Dieser Code hat die unglückliche Nebenwirkung abhängig zu sein, zu wissen, welcher Thread zurückkehren erste, though.

Wenn Sie jedoch nur versuchen, herauszufinden, wie Ereignisse vom Server zum Client gesendet werden (und HTML 5 ist eine Option), würde ich empfehlen, in server-sent events (oder Web-Sockets, wenn Sie Vollduplex-Kommunikation benötigen)).Wenn html 5 keine Option ist, glaube ich, dass Sie einige Javascript-Hacks verwenden können, um Web-Sockets zu simulieren. Sie können über einige dieser here und here lesen.

edit: hinzugefügt Links für Nicht-HTML 5 Alternativen

0

Sind Sie in der Lage zu früheren Versionen .NET 4.5 oder sind Sie beschränkt zu benutzen? v4.5 hat viele neue Funktionen, die das Erstellen von asynchronen Methoden sehr einfach machen, ohne sich um das Thread-Management kümmern zu müssen. Dieser Link hat eine gute Erklärung, wie ein asynchrones Verfahren mit der neuen Task Aufgabe und async/await Operatoren zu implementieren: Working with Asynchronous Operations in ASP.NET 4.5 Web Forms

Im Wesentlichen würden Sie nur ein Task für jede Methode, die für die Aktualisierung der Update und es schaffen müssen, um Feuer beim Laden der Seite. Am Ende kann jeder Task für 5 oder 10 Sekunden schlafen, bevor er sich selbst anruft, um Ihnen den gewünschten Effekt zu geben.

0

Stattdessen können Sie 2 Timer-Steuerelemente verwenden, ein mit Intervall von 5000 und ein weiteres mit Intervall von 10000

1

einfach einen Trigger-Tag in jedem Update setzen auf eine asp zeigen: Timer und eingestellte Zeit bis 5000 und 10000 Millisekunden.

Im Folgenden finden Sie die Lösung, die Sie fragen, Update verwenden, sondern weil je 5 und 10 Sekunden sorgen dort ein Postback für Timer gebrannt ist:

Ich empfehle die Verwendung von JavaScript oder jQuery zu vermeiden Postbacks.

ASPX:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" 
    Inherits="WebApplication1.Default" %> 
<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head id="Head1" runat="server"> 
    <title></title> 
</head> 
<body> 
    <form id="form1" runat="server"> 
     <asp:ScriptManager ID="ScriptManager1" runat="server"/> 

     5 sec: 
     <asp:UpdatePanel ID="UpdatePanel1" runat="server"> 
      <Triggers> 
       <asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick"/> 
      </Triggers> 
      <ContentTemplate> 
       <asp:Label ID="Label2" runat="server" Text="Label"/><br /> 
      </ContentTemplate> 
     </asp:UpdatePanel> 
     <asp:Timer ID="Timer1" runat="server" Interval="5000" 
      OnTick="Timer1_Tick"/><br /> 

     10 sec: 
     <asp:UpdatePanel ID="UpdatePanel2" runat="server"> 
      <Triggers> 
       <asp:AsyncPostBackTrigger ControlID="Timer2" EventName="Tick"/> 
      </Triggers> 
      <ContentTemplate> 
       <asp:Label ID="Label1" runat="server" Text="Label"/><br /> 
      </ContentTemplate> 
     </asp:UpdatePanel> 
     <asp:Timer ID="Timer2" runat="server" Interval="10000" 
      OnTick="Timer2_Tick"/> 
    </form> 
</body> 
</html> 

C#

using System; 

namespace WebApplication1 
{ 
    public partial class Default : System.Web.UI.Page 
    { 
     protected void Timer1_Tick(object sender, EventArgs e) 
     { 
      this.Label2.Text = "Done in 5 sec!"; 
     } 

     protected void Timer2_Tick(object sender, EventArgs e) 
     { 
      this.Label1.Text = "Done in 10 sec!"; 
     } 
    } 
} 
Verwandte Themen