EXECUCAO DE SUB FORM... USA-SE THREADS?

GGERMINIANI 08/08/2013 17:16:27
#427286
Pessoal,

Estou com o seguinte problema...


Quero executar uma função e enquanto isso uma outra também deve ser executada até a 1ª terminar.



Vamos facilitar o entendimento:

1ª função: Disparar Backup
2ª função: load num form escrito: EXECUTANDO.

Quero que quando o usuário clique no menu BACKUP do formulário MDI, primeiramente eu chamo um SUB já pronta para fazer o backup,

Junto a isso, fiz um FORM que contém um GIF de load - este FORM não contém nenhum control button e é chamado por um ShowDialog, ou seja, é somente para [Ô]travar a tela do usuário.

Depois que a SUB BACKUP terminar, gostaria que o form LOADING fechasse.

Acredito que seja feito com Threads, mas sinceramente tentei algumas hipóteses e não consegui.

Óh, quem poderá me ajudar?!?!


Vlwwwwwww
KERPLUNK 08/08/2013 17:22:44
#427289
Para poder executar rotinas thread-safe, elas não deveriam estar em forms, mas sim em classes separadas. No form você chama a rotina da classe que você quer que seja rodada em uma thread. Threads e windows forms não conversam lá muito bem, não é impossível, mas também não é aconselhável.
GGERMINIANI 08/08/2013 17:33:11
#427290
Não sei se entendi muito bem.


Ao clicar em backup, devo chamar o form LOADING.

Dentro do evento Load do form, executo um thread? é isso?
ASHKATCHUP 08/08/2013 18:02:09
#427292
Pelo que entendi, tu somente quer mostrar um [Ô]loading[Ô] enquanto uma função é processada. Certo?

Então, por que tu não exibe o form de load ANTES e depois aciona a função de backup?
KERPLUNK 08/08/2013 18:02:49
#427293
1 - Faça sua rotina de backup em uma classe separada
2 - De dentro do form, instancie a classe criada e chame o método de backup por delegate.
GGERMINIANI 09/08/2013 15:34:24
#427348
KERPLUNK, para ser sincero não conhecia delegate... pode me orientar por favor?

Numa classe separada tenho o código

Public Class Backup

Public Shared Sub DispararBackup()
[ô][código do backup]
End Sub

End Class



No meu MDI clico em BACKUP

Public Class PrincipalForm
Private Sub EventoMenu_Click(ByVal sender As Object, ByVal e As System.EventArgs)
[ô][códdigos...]
LoadingForm.sub = [Ô]backup[Ô]
LoadingForm.ShowDialog()
End Sub
End Class



No load do formulário LoadingForm eu chamo a sub Backup??

Public Class LoadingForm 
Private Sub LoadingForm _Load(sender As Object, e As EventArgs) Handles MyBase.Load
[ô][códdigos...]
If sub = [Ô]backup[Ô] then
Backup.DispararBackup()
Me.Hide()
End If
End Sub
End Class



Grato.
GGERMINIANI 12/08/2013 17:22:05
#427437
Tentei fazer da forma que cito acima, mas o form LOADING nem chega a ser carregado
LUIS.HERRERA 13/08/2013 09:14:54
#427448
Germiniani eu faço um procedimento um pouco diferente. No midi coloquei um loading igual ao do navegador (animação de círculo girando), pego aqui no VBM.

Depois ao acionar um form (poderia ser qualquer método, inclusive o seu), você inicia o Threads e monitora seu final, para ocultar a animação. Abaixo como faço:

Você tem que incluir um componente BackgroundWorker do VS no seu MDI

Item do menu para acionar um método ou form
            AtivaLoading();
this.Refresh();
try
{ //-> testa a conexão com SQL se der erro evita abrir o formulário

//Codigo Foxman VBMaia
BackgroundWorker bw = new BackgroundWorker();
bw.WorkerSupportsCancellation = true;
bw.WorkerReportsProgress = true;
bw.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);
bw.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker_ProgressChanged);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker_RunWorkerCompleted);

bw.RunWorkerAsync();
while (bw.IsBusy)
{
Application.DoEvents();
}

if (resultado != true) //-> Aqui checo se final do teste de serviço SQL e Banco está ativos vindos do evento da thread.
{
MessageBox.Show([Ô]ErroAbrirForm[Ô], [Ô]TituloAvisoMSG[Ô], MessageBoxButtons.OK, MessageBoxIcon.Stop);
DesativaLoading();
return;
}
}
catch (Exception)
{
MessageBox.Show([Ô]ErroAbrirForm[Ô], [Ô]TituloAvisoMSG[Ô], MessageBoxButtons.OK, MessageBoxIcon.Stop);
DesativaLoading();
return; //-> cancela abertura
}


Ativa Loading aciona um controle de animação, inclua o seu aqui

Os eventos da Thtead são esses
 private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{ //-> Dispara teste de verificação se serviço SQL e Banco está acessíveis
IniciaTesteBanco(); [txt-color=#e80000]//inclua aqui seu backup[/txt-color] }

//-> Método executado durante execução do thread
private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//não precisei utilizar, mas se tiver necessidade....
}

//-> Método executado ao fim do thread
private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
DesativaLoading();
}


Nota: Usei uma variável privada no MDI para fazer o teste do SQL ativo, você pode usar para identificar o fim do seu backup, a variável voi ( resultado ).
GGERMINIANI 13/08/2013 10:54:34
#427458
Luis,
Bom dia.

Achei seu método interessante, vou tentar por ele...

Me surgiram algumas dúvidas... acho que inicialmente sobre o AtivaLoading e o DesativaLoading

Que métodos seriam esses? No caso seria o equivalente à eu chamar o meu form Loading?

Grato,
Gustavo.
GGERMINIANI 13/08/2013 11:33:30
#427463
Luis,
Olá novamente.

Fiz do modo que vc sugeriu e consegui parcialmente!

No botão do menu, ficou assim:

  Private Sub EventoMenu_Click(ByVal sender As Object, ByVal e As System.EventArgs)

[ô]...
Case [Ô]28_disparar_backup[Ô]

AguardeForm.Show()

Try
Me.BackgroundWorker.RunWorkerAsync()
Catch generatedExceptionName As Exception
MessageBox.Show([Ô]ErroAbrirForm[Ô], [Ô]TituloAvisoMSG[Ô], MessageBoxButtons.OK, MessageBoxIcon.[Stop])
AguardeForm.Hide()
Return
End Try

[ô]...
End Sub


Background Trabalhando:
Private Sub BackgroundWorker_DoWork(sender As Object, e As DoWorkEventArgs) Handles BackgroundWorker.DoWork

Try
Backup.DispararBackup()
Catch ex As Exception
MessageBox.Show(ex.Message, [Ô]Alerta de Erro[Ô], MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try

End Sub


Background Finalizado:
    Private Sub BackgroundWorker_RunWorkerCompleted1(sender As Object, e As RunWorkerCompletedEventArgs) Handles BackgroundWorker.RunWorkerCompleted

System.Threading.Thread.Sleep(3000)
AguardeForm.Hide()
MsgBox([Ô]Completo[Ô])

End Sub


O único problema é que eu gostaria que o Form AguardeForm fosse chamado em ShowDialog, pois assim inibiria o usuário de mexer no sistema durante esta tarefa. Porem se eu chamo por Dialog, a execução para nesta linha, não dando continuidade ao resto do código.

Se vc tiver uma dica de como fazer seria ótimo! Mas considero 90% concluído

Obrigado!
Tópico encerrado , respostas não são mais permitidas