AO LIBERAR FORM, A ROTINA CONTINUA...
Bom dia amigos.
Quando fecho um formulário, através de "Unload Me", no momento em que uma rotina está ainda dentro de um laço de repetição, o formulário é, aparentemente, descarregado, mas a rotina ainda continua executando, em segundo plano.
Como descobri: A cada iteração desse laço, são feitas algumas consultas e outras execuções em banco, o que sempre deu um "delay" perceptÃÂÂvel (apesar de todos os 'DoEvents'), então, mesmo depois que fecho o formulário, sente-se o velho delay, tipicamente pulsando em cada iteração...
Então, estou fechando o formulário de forma errada? Há uma maneira mais otimizada de fechar, que garanta o encerramento de todas as rotinas que estejam em execução?
Obrigado!
Quando fecho um formulário, através de "Unload Me", no momento em que uma rotina está ainda dentro de um laço de repetição, o formulário é, aparentemente, descarregado, mas a rotina ainda continua executando, em segundo plano.
Como descobri: A cada iteração desse laço, são feitas algumas consultas e outras execuções em banco, o que sempre deu um "delay" perceptÃÂÂvel (apesar de todos os 'DoEvents'), então, mesmo depois que fecho o formulário, sente-se o velho delay, tipicamente pulsando em cada iteração...
Então, estou fechando o formulário de forma errada? Há uma maneira mais otimizada de fechar, que garanta o encerramento de todas as rotinas que estejam em execução?
Obrigado!
isso é comportamento normal de uma rotina...
agora se vc quer abandonar o laço vc faz uma verificar e usa o comando exit for e depois exit sub para interromper.
agora se vc quer abandonar o laço vc faz uma verificar e usa o comando exit for e depois exit sub para interromper.
Na verdade tem dois problemas ai.
Primeiro usar DoEvents e rotinas longas é suicÃÂÂdio, pois essa rotina come muito processamento da máquina e acaba demorando umas 10 vezes mais tempo pra terminar. Use a api GetInputState() para detectar o pedido de processamento e ai sim use DoEvents para fornece a permissão só quando pedido.
Outra coisa para cancelar o laço não é só fechar o form não. é preciso sair da rotina, então criamos uma variavel booleana para informar que um pedido de cancelamento ocorreu e então "Exit Do" ou "Exit For" dependo do tipo de laço que você criou.
Exemplo para teste, desenhe dois label e dois command no form. E na área de código cole isso:
Tenta ai, abraços...
Primeiro usar DoEvents e rotinas longas é suicÃÂÂdio, pois essa rotina come muito processamento da máquina e acaba demorando umas 10 vezes mais tempo pra terminar. Use a api GetInputState() para detectar o pedido de processamento e ai sim use DoEvents para fornece a permissão só quando pedido.
Outra coisa para cancelar o laço não é só fechar o form não. é preciso sair da rotina, então criamos uma variavel booleana para informar que um pedido de cancelamento ocorreu e então "Exit Do" ou "Exit For" dependo do tipo de laço que você criou.
Exemplo para teste, desenhe dois label e dois command no form. E na área de código cole isso:
Private Declare Function GetInputState Lib "user32" () As Long
Private vCancelar As Boolean 'Essa é a variável de cancelamento
Private Sub Command1_Click()
Dim lngCounter As Long, Inic As Date
vCancelar = False
Me.MousePointer = vbHourglass
Inic = Time
' Qualquer loop longo que possa precisar ser interrompido.
For lngCounter = 0 To 10000000
If lngCounter Mod 100 Then
' Entra aqui somente de 100 em 100 iterações.
If GetInputState() <> 0& Then
' Um evento do mouse ou keyboard está na fila de
' mensagens, então, chamamos o DoEvents para que
' a mensagem seja processada.
DoEvents
If vCancelar Then
' O usuário cancelou o processo.
Exit For
End If
End If
End If
Next lngCounter
Label1.Caption = DateDiff("s", Inic, Time)
Inic = Time
' Qualquer loop longo que possa precisar ser interrompido.
For lngCounter = 0 To 10000000
If lngCounter Mod 100 Then
' Entra aqui somente de 100 em 100 iterações.
DoEvents
If vCancelar Then
' O usuário cancelou o processo.
Exit For
End If
End If
Next lngCounter
Label2.Caption = DateDiff("s", Inic, Time)
Me.MousePointer = vbDefault
End Sub
Private Sub Command2_Click()
' O usuário cancelou o processo.
vCancelar = True
End Sub
Tenta ai, abraços...
Valeu MJ,
Realmente nunca tinha parado pra pensar no DoEvents dessa forma, pois tempo de processamento por aqui é absolutamente irrisório em relação ao tempo gasto com consultas de banco (em tabelas com milhões de registros). Tenho despendido mais tempo otimizando a modelagem, métodos de acesso e instruções SQL.
Abraços!
Realmente nunca tinha parado pra pensar no DoEvents dessa forma, pois tempo de processamento por aqui é absolutamente irrisório em relação ao tempo gasto com consultas de banco (em tabelas com milhões de registros). Tenho despendido mais tempo otimizando a modelagem, métodos de acesso e instruções SQL.
Abraços!
Tópico encerrado , respostas não são mais permitidas