Die englische Version finden Sie unter: http://dflying.dflying.net/1/archive/100_building_a_real_time_progressbar_using_aspnet_atlas.html
Wenn einige langfristige Vorgänge im Hintergrund ausgeführt werden, wäre es eine sehr seltene Errungenschaft, wenn auf der Seite ein Fortschrittsbalken bereitgestellt werden könnte, der den tatsächlichen Fortschritt anzeigt, anstatt Benutzer unwissentlich warten zu lassen oder einfache Schätzungen in der Vergangenheit vorzunehmen. Ort. Mit ASP.NET Atlas ist dies jetzt durchaus möglich. In diesem Artikel wird erläutert, wie diese Funktionalität erreicht wird, und einige grundlegende Konzepte zur Entwicklung von Atlas-Client-Steuerelementen vorgestellt. Sie können hier auch Beispielprogramme und Quelldateien herunterladen.
Die Idee, einen Fortschrittsbalken auf einer Webseite zu implementieren, ist eigentlich sehr einfach: Schreiben Sie ein clientseitiges Atlas-Steuerelement, fordern Sie von Zeit zu Zeit den Server an und verwenden Sie die zurückgegebenen aktuellen Fortschrittsdaten, um die Anzeige des Fortschrittsbalkens zu aktualisieren . In diesem Beispiel gibt es vier Teile des Codes:
einen Webdienst, dessen Fertigstellung lange dauert
Ein Webdienst, der zum Abfragen des Fortschritts des oben genannten Webdiensts verwendet wird
Das Client-Atlas-Fortschrittsbalken-Steuerelement (ProgressBar) ist für die Verwaltung der Client-Logik und die Ausgabe der visuellen Benutzeroberfläche verantwortlich. Dies ist auch die wichtigste Komponente in diesem Beispiel und kann in Zukunft bei der Entwicklung anderer Seiten oder Programme wiederverwendet werden. Eine ASP.NET-Testseite, die den oben genannten Webdienst und die Steuerelemente enthält. Im Folgenden implementieren wir die oben genannten vier Schritte :
Es dauert lange. Ein Webdienst, dessen Abschluss lange dauert.
In einem tatsächlichen Programm kann ein Webdienst, dessen Abschluss lange dauert, die folgende Anweisung haben:
1[WebMethod]
2public void TimeConsumingTask()
3{
4 ConnectToDataBase();
5 GetSomeValueFromDataBase();
6 CopySomeFilesFromDisk();
7 GetARemoteFile();
8}
Auf diese Weise können wir einige Hilfsmethoden einfügen, um den aktuellen Fortschrittsabschlussstatus zu bestimmen. setProgress(int) wird verwendet, um den aktuellen Fortschrittsabschlussprozentsatz festzulegen:
1[WebMethod]
2public void TimeConsumingTask()
3{
4 setProgress(0);
5ConnectToDataBase();
6 setProgress(10);
7 GetSomeValueFromDataBase();
8 setProgress(40);
9 CopySomeFilesFromDisk();
10 setProgress(50);
11 GetARemoteFile();
12 setProgress(100);
13}
In diesem Beispiel verwenden wir den Cache nur zum Speichern von Fortschrittsabschlussinformationen und verwenden die Thread.Sleep()-Methode, um die Verzögerung des Vorgangs zu simulieren:
1[WebMethod]
2public int StartTimeConsumingTask()
3{
4 Zeichenfolge ProcessKey = this.Context.Request.UserHostAddress;
5 string threadLockKey = "thread" + this.Context.Request.UserHostAddress;
6 Objekt threadLock = this.Context.Cache[threadLockKey];
7 if (threadLock == null)
8 {
9 threadLock = neues Objekt();
10 this.Context.Cache[threadLockKey] = threadLock;
11 }
12
13 // Nur 1 laufende Aufgabe pro Benutzer zulassen.
14 if (!Monitor.TryEnter(threadLock, 0))
15 Rückkehr -1;
16
17 DateTime startTime = DateTime.Now;
18
19 // Simulieren Sie eine zeitaufwändige Aufgabe.
20 für (int i = 1; i <= 100; i++)
einundzwanzig {
22 // Den Fortschritt für diese Aufgabe aktualisieren.
23 this.Context.Cache[processKey] = i;
24 Thread.Sleep(70);
25}
26
27 Monitor.Exit(threadLock);
28
29 return (DateTime.Now - startTime).Seconds;
30}
31
Der Webdienst zum Abfragen des Fortschritts
ist einfach zu implementieren. Rufen Sie einfach die Fortschrittsinformationen aus dem Cache ab:
1[WebMethod]
2public int GetProgress()
3{
4 Zeichenfolge ProcessKey = this.Context.Request.UserHostAddress;
5 Objektfortschritt = this.Context.Cache[processKey];
6 if (Fortschritt != null)
7 {
8 return (int)progress;
9}
10
11 gibt 0 zurück;
12}
Clientseitiges Fortschrittsbalken-Steuerelement (ProgressBar)
Schritt 1: Von Sys.UI.Control erben
Das ProgressBar-Steuerelement sollte von der Basisklasse des Atlas-Steuerelements Sys.UI.Control erben und es als versiegelte Klasse (versiegelte Klasse) deklarieren nicht mehr vererbt werden) ). Die Basisklasse Sys.UI.Control enthält einige Operationen und Methoden, die allen Steuerelementen gemeinsam sind. Verknüpfen Sie sich beispielsweise mit einem HTML-Element (auch als Bindung bezeichnet) usw. Gleichzeitig muss es registriert werden, um Atlas über diesen neuen Typ zur künftigen Deklaration und Verwendung zu informieren, damit Atlas beispielsweise die Beschreibung dieses Typs usw. erhalten kann.
1Sys.UI.ProgressBar = function(associatedElement) {
2 Sys.UI.ProgressBar.initializeBase(this, [associatedElement]);
3
4}
5Type.registerSealedClass('Sys.UI.ProgressBar', Sys.UI.Control);
6Sys.TypeDescriptor.addType('script','progressBar', Sys.UI.ProgressBar);
7
Schritt 2: Fügen Sie private Mitglieder hinzu und schreiben Sie den entsprechenden Setter/Getter.
Als Nächstes müssen Sie einige Eigenschaften hinzufügen, um unser Steuerelement festzulegen. In diesem Beispiel benötigen wir drei Eigenschaften:
Intervall Das Intervall zwischen jeder erneuten Abfrage des Fortschritts und der Aktualisierung des Fortschrittsbalkens. Einheit: Millisekunde
Dienst-URL. Der Pfad der Webdienstdatei.
Servicemethode. Der Name der Methode zum Abrufen von Fortschrittsinformationen.
Diese Eigenschaften sollten sich strikt an die Namenskonvention von Atlas halten: Getter sollten mit „get_“ beginnen und Setter sollten mit „set_“ beginnen und einen Parameter übergeben. Sie müssen auch Beschreibungen dieser Eigenschaften im Deskriptor des Steuerelements hinzufügen. Die Beschreibungsmethode (Deskriptor) wird im vierten Schritt erläutert. Für das Attribut „Service-Methode“ haben wir beispielsweise die folgende Anweisung:
1var _serviceMethod;
2
3this.get_serviceMethod = function() {
4 return _serviceMethod;
5}
6
7this.set_serviceMethod = function(value) {
8 _serviceMethod = value;
9}
Schritt 3: Verwenden Sie das Timer-Steuerelement, um das Webdienstsystem
von Zeit zu Zeit abzufragen. Der Timer wird verwendet, um jedes Mal eine Methode aufzurufen (ein Ereignis auszugeben). Wir können einen Delegaten definieren, der auf diese Methode zeigt und dies jedes Mal tut Fragen Sie diesen Webdienst innerhalb eines Zeitraums ab. Um Browser-Speicherlecks zu vermeiden, sollten Sie daran denken, einige notwendige Aufräumarbeiten durchzuführen, wenn das Steuerelement zerstört (entsorgt) wird.
Beachten Sie außerdem, dass Sie keine zweite Anfrage senden sollten, wenn die vorherige Anfrage nicht zurückgegeben wurde.
1var _timer = new Sys.Timer();
2var _responsePending;
3var _tickHandler;
4var _obj = this;
5
6this.initialize = function() {
7 Sys.UI.ProgressBar.callBaseMethod(this, 'initialize');
8 _tickHandler = Function.createDelegate(this, this._onTimerTick);
9 _timer.tick.add(_tickHandler);
10 this.set_progress(0);
11}
12
13this.dispose = function() {
14 if (_timer) {
15 _timer.tick.remove(_tickHandler);
16 _tickHandler = null;
17 _timer.dispose();
18}
19 _timer = null;
20 assoziiertesElement = null;
21 _obj = null;
zweiundzwanzig
23 Sys.UI.ProgressBar.callBaseMethod(this, 'dispose');
vierundzwanzig}
25
26this._onTimerTick = function(sender, eventArgs) {
27 if (!_responsePending) {
28 _responsePending = true;
29
30 // Rufen Sie die Dienstmethode asynchron auf.
31 Sys.Net.ServiceMethod.invoke(_serviceURL, _serviceMethod, null, null, _onMethodComplete);
32}
33}
34
35function _onMethodComplete(result) {
36 // Fortschrittsbalken aktualisieren.
37 _obj.set_progress(result);
38 _responsePending = false;
39}
Schritt 4: Steuerungsmethode hinzufügen
Wir sollten in der Lage sein, den Start/Stopp des Fortschrittsbalkens zu steuern. Darüber hinaus ist für eine Atlas-Steuerung auch die zugehörige Beschreibungsmethode (Deskriptor) erforderlich. Atlas wird es verwenden, um diese Art von Informationen zu beschreiben.
1this.getDescriptor = function() {
2 var td = Sys.UI.ProgressBar.callBaseMethod(this, 'getDescriptor');
3 td.addProperty('interval', Number);
4 td.addProperty('progress', Number);
5 td.addProperty('serviceURL', String);
6 td.addProperty('serviceMethod', String);
7 td.addMethod('start');
8 td.addMethod('stop');
9 Return td;
10}
11
12this.start = function() {
13 _timer.set_enabled(true);
14}
15
16this.stop = function() {
17 _timer.set_enabled(false);
18}
OK, die Client-Steuerung ist soweit abgeschlossen. Wir speichern es als ProgressBar.js.
ASP.NET-Testseite ASP.NET-Testseite
Für jede Atlas-Seite müssen wir als Erstes ein ScriptManager-Serversteuerelement hinzufügen. In diesem Beispiel beziehen wir uns auf das ProgressBar-Steuerelement, den Webdienst, dessen Ausführung lange dauert, und den Progress Query-Webdienst. (Diese beiden Webdienste befinden sich in derselben Datei: TaskService.asmx)
1<atlas:ScriptManager ID="ScriptManager1" runat="server" >
2 <Skripte>
3 <atlas:ScriptReference Path="ScriptLibrary/ProgressBar.js" ScriptName="Custom" />
4 </scripts>
5 <Dienste>
6 <atlas:ServiceReference Path="TaskService.asmx" />
7 </Dienste>
8</atlas:ScriptManager>
Als nächstes folgt das Layout und der Stil der Seite:
1<style type="text/css">
2* {}{
3 Schriftfamilie: Tahoma;
4}
5.progressBarContainer {}{
6 Rand: 1 Pixel durchgezogen #000;
7 Breite: 500 Pixel;
8 Höhe: 15px;
9}
10. progressBar {}{
11 Hintergrundfarbe: grün;
12 Höhe: 15px;
13 Breite: 0px;
14 Schriftstärke: fett;
15}
16</style>
17
18<div>Aufgabenfortschritt</div>
19<div class="progressBarContainer">
20 <div id="pb" class="progressBar"></div>
21</div>
22<input type="button" id="start" onclick="startTask();return false;"Starten Sie die zeitaufwändige Aufgabe!“
23<div id="output" ></div>
Schließlich gibt es noch ein Stück JavaScript zum Starten des Webdienstes, dessen Fertigstellung lange dauert und das ProgressBar-Steuerelement in die Lage versetzt, zu funktionieren:
Screenshots und Downloads
Jetzt ist alles fertig und betriebsbereit!
Seiteninitialisierung:
Läuft:
Lauf abgeschlossen:
Beispielprogramme und Quelldateien können hier heruntergeladen werden .