Pour la version anglaise, voir : http://dflying.dflying.net/1/archive/100_building_a_real_time_progressbar_using_aspnet_atlas.html
Lorsque certaines opérations à long terme sont effectuées en arrière-plan, il serait très rare qu'une barre de progression puisse être fournie sur la page pour montrer la progression réelle, au lieu de laisser les utilisateurs attendre sans le savoir ou faire de simples estimations dans le passé. lieu. Il est désormais tout à fait possible de le faire en utilisant ASP.NET Atlas. Cet article explique comment réaliser cette fonctionnalité et présente quelques concepts de base sur le développement du contrôle client Atlas. Vous pouvez également télécharger des exemples de programmes et des fichiers sources ici.
L'idée d'implémenter une barre de progression sur une page Web est en fait très simple : écrire un contrôle Atlas côté client, demander au serveur de temps en temps et utiliser les données de progression actuelles renvoyées pour mettre à jour l'affichage de la barre de progression. . Dans cet exemple, il y aura quatre parties de code :
un service Web qui prend beaucoup de temps à se terminer
Un service Web utilisé pour interroger la progression du service Web ci-dessus
Le contrôle de la barre de progression Atlas client (ProgressBar) est responsable de la maintenance de la logique client et de la sortie de l'interface utilisateur visuelle. Il s'agit également du composant le plus important dans cet exemple et peut être réutilisé dans le développement d'autres pages ou programmes à l'avenir. Une page de test ASP.NET contenant le service Web et les contrôles ci-dessus. Ci-dessous, nous implémentons les quatre étapes ci-dessus étape par étape. :
cela prend beaucoup de temps. Un service Web qui prend beaucoup de temps à se terminer
Dans un programme réel, un service Web qui prend beaucoup de temps à se terminer peut avoir l'instruction suivante :
1[WebMethod]
2public void TimeConsumingTask()
3{
4 ConnectToDataBase();
5 GetSomeValueFromDataBase();
6 CopierSomeFilesFromDisk();
7 GetARemoteFile();
8}
De cette façon, nous pouvons insérer quelques méthodes auxiliaires pour déterminer l'état d'avancement actuel. setProgress(int) est utilisé pour définir le pourcentage d'avancement actuel :
1[WebMethod]
2public void TimeConsumingTask()
3{
4 setProgress(0);
5ConnectToDataBase();
6 setProgress(10);
7 GetSomeValueFromDataBase();
8 setProgress(40);
9 CopierSomeFilesFromDisk();
10 setProgrès(50);
11 GetARemoteFile();
12 setProgress(100);
13}
Dans cet exemple, nous utilisons uniquement Cache pour stocker les informations de progression et utilisons la méthode Thread.Sleep() pour simuler le délai de l'opération :
1[WebMethod]
2public int StartTimeConsumingTask()
3{
4 chaînes processKey = this.Context.Request.UserHostAddress ;
5 chaînes threadLockKey = "thread" + this.Context.Request.UserHostAddress ;
6 objet threadLock = this.Context.Cache[threadLockKey];
7 si (threadLock == null)
8 {
9 threadLock = nouvel objet ();
10 this.Context.Cache[threadLockKey] = threadLock;
11 }
12
13 // N'autoriser qu'une seule tâche en cours d'exécution par utilisateur.
14 si (!Monitor.TryEnter(threadLock, 0))
15 retour -1 ;
16
17 DateTime startTime = DateTime.Now ;
18
19 // Simulez une tâche chronophage.
20 pour (int i = 1; i <= 100; i++)
vingt-et-un {
22 // Mettre à jour la progression de cette tâche.
23 this.Context.Cache[processKey] = i;
24 fils. Sommeil (70);
25}
26
27 Moniteur.Exit(threadLock);
28
29 return (DateTime.Now - startTime).Seconds;
30}
31
Le service Web permettant d'interroger la progression
est facile à mettre en œuvre, il suffit d'obtenir les informations de progression à partir du cache :
1[WebMethod]
2public int GetProgress()
3{
4 chaînes processKey = this.Context.Request.UserHostAddress ;
5 progression de l'objet = this.Context.Cache[processKey];
6 si (progrès != null)
7 {
8 renvoie (int)progrès ;
9}
10
11 renvoie 0 ;
12}
Contrôle de la barre de progression côté client (ProgressBar)
Étape 1 : hériter de Sys.UI.Control
Le contrôle ProgressBar doit hériter de la classe de base du contrôle Atlas Sys.UI.Control et la déclarer comme une classe scellée (classe scellée, qui peut ne plus être hérité) ). La classe de base Sys.UI.Control contient certaines opérations et méthodes communes à tous les contrôles. Par exemple, vous associer à un élément HTML (également appelé liaison), etc. En même temps, il doit être enregistré pour informer Atlas de ce nouveau type en vue d'une déclaration et d'une utilisation ultérieure, par exemple, afin qu'Atlas puisse obtenir la description de ce type, etc.
1Sys.UI.ProgressBar = fonction (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
Étape 2 : Ajouter des membres privés et écrire le Setter/Getter correspondant
Ensuite, vous devez ajouter quelques propriétés pour définir notre contrôle. Dans cet exemple, nous avons besoin de trois propriétés :
Intervalle. L'intervalle entre chaque fois que la progression est réinterrogeée et que la barre de progression est mise à jour. Unité : milliseconde
URL du service. Chemin d'accès au fichier du service Web.
Méthode de service. Nom de la méthode permettant d’obtenir des informations de progression.
Ces propriétés doivent suivre strictement la convention de dénomination d'Atlas : les getters doivent commencer par 'get_' et les Setter doivent commencer par 'set_' et transmettre un paramètre. Vous devez également ajouter des descriptions de ces propriétés dans le descripteur du contrôle. La méthode de description (descripteur) sera expliquée dans la quatrième étape. Par exemple, pour l'attribut Service Method, nous avons l'instruction suivante :
1var _serviceMethod;
2
3this.get_serviceMethod = fonction() {
4 return _serviceMethod;
5}
6
7this.set_serviceMethod = fonction (valeur) {
8 _serviceMethod = valeur ;
9}
Étape 3 : utilisez le contrôle Timer pour interroger le
système de service Web de temps en temps. Timer est utilisé pour appeler une méthode (émettre un événement) à chaque fois. Nous pouvons définir un délégué pour pointer vers cette méthode et le faire à chaque fois. interrogez ce service Web dans un délai donné. Afin d'éviter les fuites de mémoire du navigateur, n'oubliez pas d'effectuer le nettoyage nécessaire lorsque le contrôle est détruit (élimination).
Notez également que vous ne devez pas envoyer une deuxième demande lorsque la demande précédente n'a pas été renvoyée.
1var _timer = new Sys.Timer();
2var _responsePending;
3var _tickHandler;
4var _obj = ceci ;
5
6this.initialize = fonction() {
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 = fonction() {
14 si (_timer) {
15 _timer.tick.remove(_tickHandler);
16 _tickHandler = nul ;
17 _timer.dispose();
18}
19 _timer = nul ;
20 AssociateElement = null ;
21 _obj = nul ;
vingt-deux
23 Sys.UI.ProgressBar.callBaseMethod(this, 'dispose');
vingt-quatre}
25
26this._onTimerTick = fonction (expéditeur, eventArgs) {
27 si (!_responsePending) {
28 _responsePending = vrai ;
29
30 // Appelez de manière asynchrone la méthode de service.
31 Sys.Net.ServiceMethod.invoke(_serviceURL, _serviceMethod, null, null, _onMethodComplete);
32}
33}
34
35fonction _onMethodComplete(résultat) {
36 // Mettre à jour la barre de progression.
37 _obj.set_progress(résultat);
38 _responsePending = faux ;
39}
Étape 4 : Ajouter une méthode de contrôle
Nous devrions pouvoir contrôler le démarrage/arrêt de la barre de progression. De plus, pour un champ Atlas, la méthode de description associée (descripteur) est également nécessaire. Atlas l'utilisera pour décrire ce type d'informations.
1this.getDescriptor = fonction() {
2 var td = Sys.UI.ProgressBar.callBaseMethod(this, 'getDescriptor');
3 td.addProperty('intervalle', Nombre);
4 td.addProperty('progrès', Nombre);
5 td.addProperty('serviceURL', String);
6 td.addProperty('serviceMethod', String);
7 td.addMethod('start');
8 td.addMethod('stop');
9 retour td ;
10}
11
12this.start = fonction() {
13 _timer.set_enabled(true);
14}
15
16this.stop = fonction() {
17 _timer.set_enabled(false);
18}
OK, le contrôle client est terminé jusqu'à présent. Nous l'enregistrons sous ProgressBar.js.
Page de test ASP.NET Page de test ASP.NET
Pour toute page Atlas, la première chose que nous devons faire est d'ajouter un contrôle serveur ScriptManager. Dans cet exemple, nous ferons référence au contrôle ProgressBar, au service Web dont l'exécution est longue et au service Web Progress Query. (Ces deux services Web se trouvent dans le même fichier : TaskService.asmx)
1<atlas:ScriptManager ID="ScriptManager1" runat="server" >
2 <Scripts>
3 <atlas:ScriptReference Path="ScriptLibrary/ProgressBar.js" ScriptName="Custom" />
4 </scripts>
5 <Prestations>
6 <atlas:ServiceReference Path="TaskService.asmx" />
7 </Services>
8</atlas:ScriptManager>
Vient ensuite la mise en page et le style de la page :
1<style type="text/css">
2* {}{
3 familles de polices : tahoma ;
4}
5.progressBarContainer {}{
6 bordure : 1px solide #000 ;
7 largeur : 500 px ;
8 hauteur : 15px ;
9}
10. barre de progression {}{
11 couleurs de fond : vert ;
12 hauteur : 15 px ;
13 largeur : 0px ;
14 poids de police : gras ;
15}
16
17
18<div>Progression de la tâche</div>
19<div class="progressBarContainer">
20 <div id="pb" class="progressBar"></div>
21</div>
22<input type="button" id="start" onclick="startTask();return false;" value="Démarrer la tâche chronophage !"
23<div id="output" ></div>
Enfin, il existe un morceau de JavaScript pour démarrer le service Web qui prend beaucoup de temps et permet au contrôle ProgressBar de commencer à fonctionner :
Captures d'écran et téléchargements
Maintenant, tout est fait et prêt à fonctionner !
Initialisation des pages :
En cours d'exécution:
Exécution terminée :
Des exemples de programmes et de fichiers sources peuvent être téléchargés ici .