Английскую версию см.: http://dflying.dflying.net/1/archive/100_building_a_real_time_progressbar_using_aspnet_atlas.html .
Когда в фоновом режиме выполняются какие-то долгосрочные операции, было бы очень редким достижением, если бы на странице можно было разместить индикатор выполнения, показывающий реальный прогресс, вместо того, чтобы позволять пользователям неосознанно ждать или делать простые оценки в прошлом. место. Теперь это вполне возможно сделать с помощью ASP.NET Atlas. В этой статье мы обсудим, как реализовать эту функциональность, и представим некоторые основные понятия о разработке клиентских элементов управления Atlas. Вы также можете скачать примеры программ и исходные файлы здесь.
Идея реализации индикатора выполнения на веб-странице на самом деле очень проста: напишите клиентский элемент управления Atlas, время от времени запрашивайте сервер и используйте возвращаемые текущие данные о ходе выполнения для обновления отображения индикатора выполнения. . В этом примере будет четыре части кода:
веб-служба, выполнение которой занимает много времени.
Веб-служба, используемая для запроса хода выполнения вышеуказанной веб-службы.
Элемент управления клиентского индикатора выполнения Atlas (ProgressBar) отвечает за поддержку клиентской логики и вывод визуального пользовательского интерфейса. Это также наиболее важный компонент в этом примере, и его можно повторно использовать при разработке других страниц или программ в будущем. Тестовая страница ASP.NET, содержащая указанную выше веб-службу и элементы управления. Ниже мы шаг за шагом реализуем вышеуказанные четыре шага. :
требуется много времени. Веб-служба, выполнение которой занимает много времени.
В реальной программе веб-служба, выполнение которой занимает много времени, может иметь следующий оператор:
1[WebMethod]
2public void TimeConsumingTask()
3{
4 Подключиться к базе данных();
5 ПолучитьНекотороеЗначениеИзБазыДанных();
6 КопироватьНекоторыеФайлыС Диска();
7 ПолучитьARemoteFile();
8}
Таким образом, мы можем вставить некоторые вспомогательные методы для определения текущего статуса завершения прогресса. setProgress(int) используется для установки текущего процента завершения прогресса:
1[WebMethod]
2public void TimeConsumingTask()
3{
4 setProgress(0);
5Подключиться к базе данных();
6 setProgress(10);
7 ПолучитьНекотороеЗначениеИзБазыДанных();
8 setProgress(40);
9 КопироватьНекоторыеФайлыС Диска();
10 комплектПрогресс(50);
11 GetARemoteFile();
12 setProgress(100);
13}
В этом примере мы используем Cache только для хранения информации о ходе выполнения и используем метод Thread.Sleep() для имитации задержки операции:
1[WebMethod]
2public int StartTimeConsumingTask()
3{
4-строчный ключ процесса = this.Context.Request.UserHostAddress;
5-строчный threadLockKey = «поток» + this.Context.Request.UserHostAddress;
6 объектов threadLock = this.Context.Cache[threadLockKey];
7, если (threadLock == ноль)
8 {
9 threadLock = новый объект();
10 this.Context.Cache[threadLockKey] = threadLock;
11 }
12
13 // Разрешить только 1 запущенную задачу для каждого пользователя.
14, если (!Monitor.TryEnter(threadLock, 0))
15 возврат -1;
16
17 ДатаВремя startTime = DateTime.Now;
18
19 // Имитация трудоемкой задачи.
20 для (int i = 1; i <= 100; i++)
двадцать один {
22 // Обновляем ход выполнения этой задачи.
23 this.Context.Cache[processKey] = i;
24 Нитки.Сон(70);
25}
26
27 Monitor.Exit(threadLock);
28
29 return (DateTime.Now - startTime).Секунды;
30}
31
Веб-сервис для запроса прогресса
легко реализовать, просто получите информацию о прогрессе из кэша:
1[WebMethod]
2public int GetProgress()
3{
4-строчный ключ процесса = this.Context.Request.UserHostAddress;
5 прогресс объекта = this.Context.Cache[processKey];
6, если (прогресс!= ноль)
7 {
8 возврат (int)прогресса;
9}
10
11 вернуть 0;
12}
Клиентский элемент управления индикатором выполнения (ProgressBar)
Шаг 1. Наследование от Sys.UI.Control
Элемент управления ProgressBar должен наследовать от базового класса элемента управления Atlas Sys.UI.Control и объявить его как запечатанный класс (запечатанный класс, который может больше не наследуются) ). Базовый класс Sys.UI.Control содержит некоторые операции и методы, общие для всех элементов управления. Например, связывая себя с элементом HTML (также известным как привязка) и т. д. В то же время его необходимо зарегистрировать, чтобы сообщить Atlas об этом новом типе для будущего объявления и использования, например, чтобы Atlas мог получить описание этого типа и т. д.
1Sys.UI.ProgressBar = функция (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
Шаг 2. Добавьте частные члены и напишите соответствующий сеттер/геттер.
Далее вам нужно добавить некоторые свойства, чтобы установить наш элемент управления. В этом примере нам нужны три свойства:
Интервал Интервал между каждым повторным запросом прогресса и обновлением индикатора выполнения. Единица: миллисекунда
URL-адрес службы. Путь к файлу веб-службы.
Метод службы Имя метода получения информации о ходе выполнения.
Эти свойства должны строго соответствовать соглашению об именах Atlas: геттеры должны начинаться с «get_», а сеттер должен начинаться с «set_» и передавать параметр. Вам также необходимо добавить описания этих свойств в дескриптор элемента управления. Метод описания (дескриптор) будет объяснен на четвертом этапе. Например, для атрибута «Метод службы» у нас есть следующий оператор:
1var _serviceMethod;
2
3this.get_serviceMethod = функция() {
4 вернуть _serviceMethod;
5}
6
7this.set_serviceMethod = функция (значение) {
8 _serviceMethod = значение;
9}
Шаг 3. Используйте элемент управления «Таймер» для
периодического запроса к системе веб-службы. Таймер используется для каждого вызова метода (генерации события). Мы можем определить делегат, который будет указывать на этот метод, и делать это каждый раз. time. Запросите эту веб-службу в течение определенного периода времени. Чтобы избежать утечек памяти браузера, не забудьте выполнить необходимую очистку при разрушении элемента управления (удалении).
Также обратите внимание, что не следует отправлять второй запрос, если предыдущий запрос не вернулся.
1var _timer = новый Sys.Timer();
2var _responsePending;
3вар _tickHandler;
4var _obj = это;
5
6this.initialize = функция() {
7 Sys.UI.ProgressBar.callBaseMethod(это, «инициализировать»);
8 _tickHandler = Function.createDelegate(this, this._onTimerTick);
9 _timer.tick.add(_tickHandler);
10 this.set_progress(0);
11}
12
13this.dispose = функция() {
14, если (_таймер) {
15 _timer.tick.remove(_tickHandler);
16 _tickHandler = ноль;
17 _timer.dispose();
18}
19 _timer = ноль;
20 AssociateElement = ноль;
21 _obj = ноль;
двадцать два
23 Sys.UI.ProgressBar.callBaseMethod(this, 'dispose');
двадцать четыре}
25
26this._onTimerTick = функция (отправитель, eventArgs) {
27, если (!_responsePending) {
28 _responsePending = правда;
29
30 // Асинхронный вызов метода службы.
31 Sys.Net.ServiceMethod.invoke(_serviceURL, _serviceMethod, null, null, _onMethodComplete);
32}
33}
34
35функция _onMethodComplete(результат) {
36 // Обновляем индикатор выполнения.
37 _obj.set_progress(результат);
38 _responsePending = ложь;
39}
Шаг 4. Добавьте метод управления.
У нас должна быть возможность контролировать начало/остановку индикатора выполнения. Более того, для элемента управления Atlas также необходим соответствующий метод описания (дескриптор). Atlas будет использовать его для описания такого типа информации.
1this.getDescriptor = функция() {
2 var td = Sys.UI.ProgressBar.callBaseMethod(this, 'getDescriptor');
3 td.addProperty('интервал', Число);
4 td.addProperty('прогресс', Число);
5 td.addProperty('serviceURL', String);
6 td.addProperty('serviceMethod', String);
7 td.addMethod('старт');
8 td.addMethod('стоп');
9 возвращение тд;
10}
11
12this.start = функция() {
13 _timer.set_enabled(истина);
14}
15
16this.stop = функция() {
17 _timer.set_enabled(ложь);
18}
Хорошо, управление клиентом завершено. Мы сохраняем его как ProgressBar.js.
Страница тестирования ASP.NET Страница тестирования ASP.NET
Для любой страницы Atlas первое, что нам нужно сделать, — это добавить серверный элемент управления ScriptManager. В этом примере мы будем ссылаться на элемент управления ProgressBar, веб-службу, выполнение которой занимает много времени, и веб-службу Progress Query. (Эти две веб-службы расположены в одном файле: TaskService.asmx)
1<atlas:ScriptManager ID="ScriptManager1" runat="server" >
2 <Скрипты>
3 <atlas:ScriptReference Path="ScriptLibrary/ProgressBar.js" ScriptName="Custom" />
4 </скрипты>
5 <Сервисы>
6 <atlas:ServiceReference Path="TaskService.asmx" />
7 </Услуги>
8</atlas:ScriptManager>
Далее идет макет и стиль страницы:
1<style type="text/css">
2* {}{
3 семейства шрифтов: tahoma;
4}
5.progressBarContainer {}{
6 граница: сплошная 1 пиксель #000;
7 ширина: 500 пикселей;
8 высота: 15 пикселей;
9}
10. индикатор прогресса {}{
11 цвет фона: зеленый;
12 высота: 15 пикселей;
13 ширина: 0 пикселей;
14 начертание шрифта: полужирный;
15}
16</стиль>
17
18<div>Ход выполнения задачи</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="Запустить трудоемкую задачу!" />
23<div id="output" >/div>
Наконец, есть фрагмент JavaScript для запуска веб-службы, выполнение которого занимает много времени и позволяет элементу управления ProgressBar начать работу:
Скриншоты и загрузки
Теперь все готово и готово к работе!
Инициализация страницы:
Бег:
Запуск завершен:
Примеры программ и исходные файлы можно скачать здесь .