Para a versão em inglês, consulte: http://dflying.dflying.net/1/archive/100_building_a_real_time_progressbar_using_aspnet_atlas.html
Quando algumas operações de longo prazo estão sendo realizadas em segundo plano, seria uma conquista muito rara se uma barra de progresso pudesse ser fornecida na página para mostrar o progresso real, em vez de deixar os usuários esperarem sem saber ou fazerem estimativas simples no passado. lugar. Agora é inteiramente possível fazer isso usando o ASP.NET Atlas. Este artigo discutirá como realizar essa funcionalidade e apresentará alguns conceitos básicos sobre o desenvolvimento de controle de cliente Atlas. Você também pode baixar programas de amostra e arquivos de origem aqui.
A ideia de implementar uma barra de progresso em uma página da web é na verdade muito simples: escrever um controle Atlas do lado do cliente, solicitar o servidor de vez em quando e usar os dados de progresso atuais retornados para atualizar a exibição da barra de progresso . Neste exemplo, haverá quatro partes de código:
um Web Service que leva muito tempo para ser concluído
Um serviço Web usado para consultar o progresso do serviço Web acima
O controle da barra de progresso do cliente Atlas (ProgressBar) é responsável por manter a lógica do cliente e gerar a UI visual. Este também é o componente mais importante neste exemplo e pode ser reutilizado no desenvolvimento de outras páginas ou programas no futuro. Uma página de teste ASP.NET contendo o serviço Web e os controles acima. Abaixo, implementamos as quatro etapas acima, passo a passo. :
leva muito tempo Serviço Web que leva muito tempo para ser concluído
Em um programa real, um Serviço Web que leva muito tempo para ser concluído pode ter a seguinte instrução:
1[WebMethod]
2public void TimeConsumingTask()
3{
4ConectToDataBase();
5GetSomeValueFromDataBase();
6 CopySomeFilesFromDisk();
7GetARemoteFile();
8}
Desta forma, podemos inserir alguns métodos auxiliares para determinar o status de conclusão do progresso atual. setProgress(int) é usado para definir a porcentagem de conclusão do progresso atual:
1[WebMethod]
2public void TimeConsumingTask()
3{
4setProgress(0);
5ConnectToDataBase();
6setProgress(10);
7GetSomeValueFromDataBase();
8setProgress(40);
9 CopySomeFilesFromDisk();
10setProgress(50);
11GetARemoteFile();
12setProgress(100);
13}
Neste exemplo, usamos Cache apenas para armazenar informações de conclusão do progresso e usamos o método Thread.Sleep() para simular o atraso da operação:
1[WebMethod]
2public int StartTimeConsumingTask()
3{
4 string processKey = this.Context.Request.UserHostAddress;
5 string threadLockKey = "thread" + this.Context.Request.UserHostAddress;
6 objeto threadLock = this.Context.Cache[threadLockKey];
7 se (threadLock == nulo)
8 {
9 threadLock = novo objeto();
10 this.Context.Cache[threadLockKey] = threadLock;
11}
12
13 // Permitir apenas 1 tarefa em execução por usuário.
14 se (!Monitor.TryEnter(threadLock, 0))
15 retorna -1;
16
17 DateTime startTime = DateTime.Now;
18
19 // Simule uma tarefa demorada.
20 para (int i = 1; i <= 100; i++)
vinte e um {
22 // Atualize o progresso desta tarefa.
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
O Web Service para consultar o progresso
é fácil de implementar, basta obter as informações de progresso do Cache:
1[WebMethod]
2public int GetProgress()
3{
4 string processKey = this.Context.Request.UserHostAddress;
5 progresso do objeto = this.Context.Cache[processKey];
6 se (progresso! = nulo)
7 {
8 retorna (int)progresso;
9}
10
11 retorna 0;
12}
Controle da barra de progresso do lado do cliente (ProgressBar)
Etapa 1: Herdar de Sys.UI.Control
O controle ProgressBar deve herdar da classe base de controle Atlas Sys.UI.Control e declará-la como uma classe selada (classe selada, que pode não será mais herdado) ). A classe base Sys.UI.Control contém algumas operações e métodos comuns a todos os controles. Por exemplo, associar-se a um elemento HTML (também conhecido como vinculação), etc. Ao mesmo tempo, deve ser registado para que o Atlas tenha conhecimento deste novo tipo para futura declaração e utilização, por exemplo, para que o Atlas possa obter a descrição deste tipo, etc.
1Sys.UI.ProgressBar = função (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
Passo 2: Adicione membros privados e escreva o Setter/Getter correspondente.
Em seguida, você precisa adicionar algumas propriedades para definir nosso controle. Neste exemplo, precisamos de três propriedades:
Intervalo O intervalo entre cada vez que o progresso é consultado novamente e a barra de progresso é atualizada. Unidade: milissegundo
URL do serviço O caminho do arquivo do serviço da Web.
Método de serviço O nome do método para obter informações de progresso.
Essas propriedades devem seguir estritamente a convenção de nomenclatura do Atlas: Getters devem começar com 'get_' e Setter devem começar com 'set_' e passar um parâmetro. Você também precisa adicionar descrições dessas propriedades no descritor do controle. O método de descrição (descritor) será explicado na quarta etapa. Por exemplo, para o atributo Service Method, temos a seguinte instrução:
1var _serviceMethod;
2
3this.get_serviceMethod=função(){
4 retornar _serviceMethod;
5}
6
7this.set_serviceMethod = função (valor) {
8 _serviceMethod = valor;
9}
Etapa 3: Use o controle Timer para consultar o Web Service
Sys de vez em quando O timer é usado para chamar um método (emitir um evento) todas as vezes. Consulte este serviço da Web dentro de um período de tempo. Para evitar vazamentos de memória do navegador, lembre-se de fazer algumas limpezas necessárias quando o controle for destruído (descarte).
Além disso, observe que você não deve enviar uma segunda solicitação quando a solicitação anterior não tiver retornado.
1var _timer = new Sys.Timer();
2var _respostaPendente;
3var _tickHandler;
4var _obj = isto;
5
6this.initialize = function() {
7 Sys.UI.ProgressBar.callBaseMethod(isto, 'inicializar');
8 _tickHandler = Function.createDelegate(isto, isto._onTimerTick);
9 _timer.tick.add(_tickHandler);
10 this.set_progress(0);
11}
12
13this.dispose = function() {
14 se (_temporizador) {
15 _timer.tick.remove(_tickHandler);
16 _tickHandler = null;
17 _timer.dispose();
18}
19 _temporizador = nulo;
20 elemento associado = null;
21 _obj = nulo;
vinte e dois
23 Sys.UI.ProgressBar.callBaseMethod(this, 'dispose');
vinte e quatro}
25
26this._onTimerTick = function(remetente, eventArgs) {
27 if (!_responsePending) {
28 _responsePending = verdadeiro;
29
30 // Chama o método de serviço de forma assíncrona.
31 Sys.Net.ServiceMethod.invoke(_serviceURL, _serviceMethod, nulo, nulo, _onMethodComplete);
32}
33}
34
35função _onMethodComplete(resultado) {
36 // Atualize a barra de progresso.
37 _obj.set_progress(resultado);
38 _respostaPendente = falso;
39}
Passo 4: Adicionar método de controle
Devemos ser capazes de controlar o início/parada da barra de progresso. Além disso, para um controle Atlas, o método de descrição relacionado (descritor) também é necessário. Atlas irá usá-lo para descrever esse tipo de informação.
1this.getDescriptor=função(){
2 var td = Sys.UI.ProgressBar.callBaseMethod(this, 'getDescriptor');
3 td.addProperty('intervalo', Número);
4 td.addProperty('progresso', Número);
5 td.addProperty('serviceURL', String);
6 td.addProperty('serviceMethod', String);
7 td.addMethod('iniciar');
8td.addMethod('parar');
9 retorno td;
10}
11
12this.start=função(){
13 _timer.set_enabled(true);
14}
15
16this.stop = function() {
17 _timer.set_enabled(falso);
18}
OK, o controle do cliente está concluído até agora. Nós o salvamos como ProgressBar.js.
Página de testes do ASP.NET Página de testes do ASP.NET
Para qualquer página do Atlas, a primeira coisa que precisamos fazer é adicionar um controle de servidor ScriptManager. Neste exemplo nos referiremos ao controle ProgressBar, ao Web Service que demora muito para ser concluído e ao Progress Query Web Service. (Esses dois Web Services estão localizados no mesmo arquivo: TaskService.asmx)
1<atlas:ScriptManager ID="ScriptManager1" runat="server" >
2 <Roteiros>
3 <atlas:ScriptReference Path="ScriptLibrary/ProgressBar.js" ScriptName="Custom" />
4 </scripts>
5 <Serviços>
6 <atlas:ServiceReference Path="TaskService.asmx" />
7 </Serviços>
8</atlas:ScriptManager>
A seguir está o layout e o estilo da página:
1<style type="text/css">
2* {}{
3 famílias de fontes: tahoma;
4}
5.progressBarContainer {}{
6 borda: 1px sólido #000;
7 largura: 500px;
8 altura: 15px;
9}
10. barra de progresso {}{
11 cor de fundo: verde;
12 altura: 15px;
13 largura: 0px;
14 espessura da fonte: negrito;
15}
16</estilo>
17
18<div>Progresso da tarefa</div>
19<div class="progressBarContainer">
20 <div id="pb" class="progressBar"></div>
21</div>
22<input type="button" id="start" onclick="startTask();return false;" Iniciar a tarefa demorada!
23<div id="saída" </div>
Por fim, existe um pedaço de JavaScript para iniciar o Web Service que demora muito para ser concluído e deixar o controle ProgressBar começar a funcionar:
Capturas de tela e downloads
Agora tudo está pronto e pronto para ser executado!
Inicialização da página:
Correndo:
Execução concluída:
Exemplos de programas e arquivos de origem podem ser baixados aqui .