none
Progress Bar + Envio de Email RRS feed

  • Pergunta

  • Tenho um botão no meu form que ao clicar envia um email... leva um tempinho para esse evento finalizar... queria colocar uma progress bar e um timer que quando o usuário clicar no botão o timer fosse disparado, e a progress bar ia sendo incrementada até terminar essa função de enviar email, retornando a mensagem para o usuário que o email foi enviado...

    Eu fiz assim:

    private void btnEnviaEmail_Click(object sender, EventArgs e)
    {
         enviarEmail();
    }

    private void enviarEmail()
    {
         timer1.Enabled = true;
         // Rotina de Envio de Email!
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
    progressBar1.Visible = true;
    progressBar1.Value = progressBar1.Value + 10;
    if (progressBar1.Value < 100)
    {
          label5.Visible = true;
          label5.Text = "Enviando Email...";
    }

    else if(progressBar1.Value.Equals(100))
    {
          timer1.Enabled = false;
          progressBar1.Visible = false;
          label5.Visible = false;
          MessageBox.Show("Mensagem Enviada com Sucesso!");
    }
    }


    Mas a impressão que dá é que não está sincronizado... quando aperto o botão demora um pouco pra progress bar aparecer... está certo esse código?

    quinta-feira, 23 de julho de 2009 15:13

Respostas

  • Jessy,

    Eu desconfio que exista um problema de sincronismo entre a thread principal (da sua aplicação) e o timer. Quando você chama o método SendAsync o sistema continua a execução enquanto a mensagem é enviada. O mesmo não acontece com o método Send.

    1 - Exemplo de Send (síncrono):

    smtpClient.Send(...);
    Console.WriteLine("Essa mensagem só aparece depois que a mensagem é enviada.");


    2 - Exemplo de SendAsync (assíncrono):

    smtpClient.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback);
    smtpClient.SendAsync(...);
    Console.WriteLine("Essa mensagem aparece enquanto a mensagem é enviada.");

    ...

    private static void SendCompletedCallback(object sender, AsyncCompletedEventArgs e)
    {
        Console.WriteLine("Essa mensagem só aparece depois que a mensagem é enviada.");
    }


    Mais informações sobre programação assíncrona:

    Asynchronous Programming Overview
    http://msdn.microsoft.com/en-us/library/2e08f6yc%28VS.71%29.aspx

    Espero ter ajudado.

    Att.

    Ari C. Raimundo
    quinta-feira, 23 de julho de 2009 19:30
    Moderador

Todas as Respostas

  • Jessy,

    Qual o valor utilizado na propriedade Interval? Veja que o evento timer1_Tick somente será acionado após o valor de tempo contido nessa propriedade.

    Att.

    Ari C. Raimundo
    quinta-feira, 23 de julho de 2009 15:43
    Moderador
  • 100

    Mas eu teria q diminuir esse valor?
    quinta-feira, 23 de julho de 2009 15:48
  • Jessy,

    O que tem nessa rotina de e-mail?

    Att.

    Ari C. Raimundo
    quinta-feira, 23 de julho de 2009 15:51
    Moderador
  • private void enviarEmail()
            {
                timer1.Enabled = true;
                SmtpClient cliente = new SmtpClient("smtp.gmail.com", 587);
                cliente.EnableSsl = true;
    
                MailAddress remetente = new MailAddress("email@gmail.com", "Email Teste");
                MailAddress destinatario = new MailAddress(txtEmail.Text, "Fulano");
                MailMessage mensagem = new MailMessage(remetente, destinatario);
                mensagem.Body = txtMensagem.Text;
                mensagem.Subject = txtAssunto.Text;
    
                NetworkCredential credenciais = new NetworkCredential("email@email.com", "senha", "");
    
                cliente.Credentials = credenciais;
    
                try
                {
                    cliente.Send(mensagem);
                }
                catch (Exception ex)
                {
                    string erro = ex.Message;
                    MessageBox.Show("Erro ao Enviar Email!");
                }
            }
    quinta-feira, 23 de julho de 2009 15:53
  • Jessy,

    Sugiro que você utilize o método SendAsync ao invés de Send. E então quando finalizar o envio do e-mail (incluir callback no método) o Timer seria desabilitado.

    Método SendAsync:
    http://msdn.microsoft.com/en-us/library/x5x13z6h.aspx

    Att.

    Ari C. Raimundo
    quinta-feira, 23 de julho de 2009 16:01
    Moderador
  • Tem como vc me dar um exemplo de como incluir callback nesse método?
    quinta-feira, 23 de julho de 2009 16:10
  • Tenho um botão no meu form que ao clicar envia um email... leva um tempinho para esse evento finalizar... queria colocar uma progress bar e um timer que quando o usuário clicar no botão o timer fosse disparado, e a progress bar ia sendo incrementada até terminar essa função de enviar email, retornando a mensagem para o usuário que o email foi enviado...

    Eu fiz assim:

    private void btnEnviaEmail_Click(object sender, EventArgs e)
    {
         enviarEmail();
    }

    private void enviarEmail()
    {
         timer1.Enabled = true;
         // Rotina de Envio de Email!
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
    progressBar1.Visible = true;
    progressBar1.Value = progressBar1.Value + 10;
    if (progressBar1.Value < 100)
    {
          label5.Visible = true;
          label5.Text = "Enviando Email...";
    }

    else if(progressBar1.Value.Equals(100))
    {
          timer1.Enabled = false;
          progressBar1.Visible = false;
          label5.Visible = false;
          MessageBox.Show("Mensagem Enviada com Sucesso!");
    }
    }


    Mas a impressão que dá é que não está sincronizado... quando aperto o botão demora um pouco pra progress bar aparecer... está certo esse código?

    quinta-feira, 23 de julho de 2009 16:40
  • Oi Jessy,

    Eu me enganei, o callback não fica no método, é um evento da classe SmtpClient (SendCompleted). No próprio link que eu lhe enviei tem um exemplo.

    Segue link com o evento:
    http://msdn.microsoft.com/en-us/library/system.net.mail.smtpclient.sendcompleted.aspx

    Att.

    Ari C. Raimundo
    quinta-feira, 23 de julho de 2009 18:10
    Moderador
  • Pq teria q usar o método SendAsync?

    Desculpa... mas ainda sou novata no c# e não entendi mto como adaptar esse exemplo ao meu problema...

    quinta-feira, 23 de julho de 2009 18:14
  • Jessy,

    Eu desconfio que exista um problema de sincronismo entre a thread principal (da sua aplicação) e o timer. Quando você chama o método SendAsync o sistema continua a execução enquanto a mensagem é enviada. O mesmo não acontece com o método Send.

    1 - Exemplo de Send (síncrono):

    smtpClient.Send(...);
    Console.WriteLine("Essa mensagem só aparece depois que a mensagem é enviada.");


    2 - Exemplo de SendAsync (assíncrono):

    smtpClient.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback);
    smtpClient.SendAsync(...);
    Console.WriteLine("Essa mensagem aparece enquanto a mensagem é enviada.");

    ...

    private static void SendCompletedCallback(object sender, AsyncCompletedEventArgs e)
    {
        Console.WriteLine("Essa mensagem só aparece depois que a mensagem é enviada.");
    }


    Mais informações sobre programação assíncrona:

    Asynchronous Programming Overview
    http://msdn.microsoft.com/en-us/library/2e08f6yc%28VS.71%29.aspx

    Espero ter ajudado.

    Att.

    Ari C. Raimundo
    quinta-feira, 23 de julho de 2009 19:30
    Moderador
  • Jessy,

    Eu desconfio que exista um problema de sincronismo entre a thread principal (da sua aplicação) e o timer. Quando você chama o método SendAsync o sistema continua a execução enquanto a mensagem é enviada. O mesmo não acontece com o método Send.

    1 - Exemplo de Send (síncrono):

    smtpClient.Send(...);
    Console.WriteLine("Essa mensagem só aparece depois que a mensagem é enviada.");


    2 - Exemplo de SendAsync (assíncrono):

    smtpClient.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback);
    smtpClient.SendAsync(...);
    Console.WriteLine("Essa mensagem aparece enquanto a mensagem é enviada.");

    ...

    private static void SendCompletedCallback(object sender, AsyncCompletedEventArgs e)
    {
        Console.WriteLine("Essa mensagem só aparece depois que a mensagem é enviada.");
    }


    Mais informações sobre programação assíncrona:

    Asynchronous Programming Overview
    http://msdn.microsoft.com/en-us/library/2e08f6yc%28VS.71%29.aspx

    Espero ter ajudado.

    Att.

    Ari C. Raimundo
    Valeu entendi agora... brigada pela ajuda e pela atenção!!!!
    sexta-feira, 24 de julho de 2009 14:39