none
Enviar e-mail assincrono RRS feed

  • Pergunta

  • Boa noite pessoal, criei uma classe para envio de notificações via e-mail, como preciso notificar o usuario de todas atualizações que acontece no sistema pois é um sistema de Help-Desk usei a classe SendAsync só que envia mas demora uns 5 a 7 segundos ou seja não libera os objetos, apresenta o mesmo tempo como no método tradicional, já procurei em vários foruns e todos demonstra o mesmo código, usei a diretiva na página Async = true pois se for false a pagina atualiza instantaneamente só que não envia alguem pode me dizer aonde esta o erro...

    public static bool EnviarEmailOcorrencia(string emaildousuario, string emailcomcopia, string mensagem, int assunto, string anexo)
            {
                try
                {
                    string servidor = WWCRMConfiguration.MailServer;
                    string email = WWCRMConfiguration.EmailServer;
                    string senha = WWCRMConfiguration.EmailSenha;
                    StringBuilder corpo = new StringBuilder();
    
                    corpo.Append("Este email foi gerado pelo Sistema, não responda.");
                    corpo.Append("</br>----------------------------------------------------");
                    corpo.Append("</br>Usuário: " + HttpContext.Current.User.Identity.Name.ToUpper());
                    corpo.Append("</br>Data: " + DateTime.Now.AddHours(WWCRMConfiguration.DifHoraServer));
                    corpo.Append("</br>Mensagem : " + mensagem);
                    corpo.Append("</br>Anexo : " + anexo);
                    corpo.Append("</br>----------------------------------------------------");
                    corpo.Append("</br><a href='http://www.meusistema.net.br'>http://www.meusistema.net.br</a>");
                    MailMessage mailMessagem = new MailMessage();
                    mailMessagem.From = new MailAddress(email);
                    mailMessagem.To.Add(emaildousuario);
                    mailMessagem.CC.Add(emailcomcopia);
                    mailMessagem.Subject = "NOVA OCORRÊNCIA nº " + assunto;
                    mailMessagem.IsBodyHtml = true;
                    mailMessagem.Body = corpo.ToString();
                    SmtpClient smtp = new SmtpClient();
                    smtp.Port = WWCRMConfiguration.PortaServer;
                    smtp.Host = servidor;
                    smtp.UseDefaultCredentials = true;
                    smtp.Credentials = new System.Net.NetworkCredential(email, senha);
                    object userState = mailMessagem;
                    smtp.SendCompleted += new SendCompletedEventHandler(cliente_SendCompleted);
                    smtp.SendAsync(mailMessagem, userState);
                    corpo.Clear();
                    mailMessagem.Dispose();
                    return true;
                }
                catch
                {
                    return false;
                }
    
            }

      public static void cliente_SendCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
            {
                MailMessage mailMessagem = e.UserState as MailMessage;
    
                if (!e.Cancelled && e.Error != null)
                {
    
                }
                else
                {
    
                }
    
            }


    Wagner

    terça-feira, 12 de novembro de 2013 23:01

Respostas

  • Fiz uma classe assim:

    public class Mail
        {
            //string emaildousuario, string emailcomcopia, string mensagem, int assunto, string anexo
            public string EmailUsuario { get; set; }
            public string EmailCopia { get; set; }
            public string Mensagem { get; set; }
            public int Assunto { get; set; }
            public string Anexo { get; set; }
        }
    
        public class MailSend
        {
            private Mail eMail { get; set; }
            public MailSend(Mail eMail)
            {
                this.eMail = eMail;
            }
            public async Task<bool> Send()
            {
                try
                {
                    string Servidor = Constantes.Servidor;
                    string EmailServidor = Constantes.EmailServidor;
                    string SenhaServidor = Constantes.SenhaServidor;
                    int PortaServidor = Constantes.PortaServidor;
                    int DifHoraServer = Constantes.DifHoraServer;
    
                    StringBuilder CorpoMensagem = new StringBuilder();
    
                    CorpoMensagem.Append("Este email foi gerado pelo Sistema, não responda.");
                    CorpoMensagem.Append("</br>----------------------------------------------------");
                    //CorpoMensagem.Append("</br>Usuário: " + (HttpContext.Current != null ? HttpContext.Current.User.Identity.Name.ToUpper() : "Anonimo"));
                    CorpoMensagem.Append("</br>Data: " + DateTime.Now.AddHours(DifHoraServer));
                    CorpoMensagem.Append("</br>Mensagem : " + eMail.Mensagem);
                    CorpoMensagem.Append("</br>Anexo : " + eMail.Anexo);
                    CorpoMensagem.Append("</br>----------------------------------------------------");
                    CorpoMensagem.Append("</br><a href='http://www.meusistema.net.br'>http://www.meusistema.net.br</a>");
                    MailMessage mailMessagem = new MailMessage();
                    mailMessagem.From = new MailAddress(EmailServidor);
                    mailMessagem.To.Add(eMail.EmailUsuario);
                    mailMessagem.CC.Add(eMail.EmailCopia);
                    mailMessagem.Subject = "NOVA OCORRÊNCIA nº " + eMail.Assunto;
                    mailMessagem.IsBodyHtml = true;
                    mailMessagem.Body = CorpoMensagem.ToString();
                    SmtpClient smtp = new SmtpClient();
                    smtp.Port = PortaServidor;
                    smtp.Host = Servidor;
                    smtp.EnableSsl = true;
                    smtp.UseDefaultCredentials = true;
                    smtp.Credentials = new System.Net.NetworkCredential(EmailServidor, SenhaServidor);
                    object userState = mailMessagem;                
                    //smtp.SendAsync(mailMessagem, userState);
                    await smtp.SendMailAsync(mailMessagem);
                    return true;               
                }
                catch
                {
                    return false;
                }
            }
        }


    E montei na página assim:

    public void ButEnviarEmail_Click(object sender, EventArgs e)
    {
    	Task task = new Task(() => Enviar());
    	task.Wait(1000);
    	task.Start();
    }
    public async void Enviar()
    {
    	Mail mail = new Mail();
    	mail.Anexo = "Anexo 1";
    	mail.Assunto = 1;
    	mail.EmailCopia = "dias.fulvio@gmail.com";
    	mail.EmailUsuario = "fulviocanducci@hotmail.com";
    	mail.Mensagem = "teste de e-mail";
    
    	MailSend mailsend = new MailSend(mail);
    	await mailsend.Send();            
    }

    E ASPX assim:

    <%@ Page Language="C#" AutoEventWireup="true" Async="true" CodeBehind="WebForm8.aspx.cs" Inherits="Img.WebForms.WebForm8" %>
    
    <!DOCTYPE html>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
            <asp:ScriptManager ID="ScriptManager1" runat="server" AjaxFrameworkMode="Enabled"></asp:ScriptManager>
        <div>
            <asp:UpdatePanel ID="UpdatePanel1" runat="server" ClientIDMode="Static" UpdateMode="Conditional">
                <ContentTemplate>
                    <asp:Button Text="Enviar E-mail" runat="server" OnClick="ButEnviarEmail_Click" ID="ButEnviarEmail" />
                    <asp:Label Text="" ID="LblMensagemEmail" runat="server" />
                </ContentTemplate>
            </asp:UpdatePanel> 
            <asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1" DisplayAfter="0" ValidateRequestMode="Enabled" ViewStateMode="Enabled" ClientIDMode="Static">
                <ProgressTemplate>Enviando ...</ProgressTemplate>
            </asp:UpdateProgress>       
        </div>
        </form>
    </body>
    </html>


    Desse jeito ele não trava a sua tela funciona perfeitamente!!!

    Obs: na linha dentro da classe terá que mudar somente isso aqui

    CorpoMensagem.Append("</br>Usuário: " + (HttpContext.Current != null ? HttpContext.Current.User.Identity.Name.ToUpper() : "Anonimo"));

    Se vai ter que passar esse valor de User no botão!!! só isso!

    Ai deixo com você! é simples!!!

    Use como exemplo não copia e cola OK!

    Vlw


    Fulvio Cezar Canducci Dias


    quarta-feira, 13 de novembro de 2013 12:56
  • Se vai passar ele antes de gerar o metodo!

    Aqui

    public void ButEnviarEmail_Click(object sender, EventArgs e)
    {
    	Task task = new Task(() => Enviar(HttpContext.Current.User.Identity.Name.ToUpper()));
    	task.Wait(1000);
    	task.Start();
    }
    public async void Enviar(String Usuario)
    {
    	Mail mail = new Mail();
    	mail.Anexo = "Anexo 1";
    	mail.Assunto = 1;
    	mail.EmailCopia = "dias.fulvio@gmail.com";
    	mail.EmailUsuario = "fulviocanducci@hotmail.com";
    	mail.Mensagem = "teste de e-mail";
    
    	MailSend mailsend = new MailSend(mail, Usuario);
    	await mailsend.Send();            
    }

    Percebe os código que eu coloquei no proprio evento que envia!!! Ali meu caro!

    testeeeeeeeeeeeeeeeeeeeeeee


    Fulvio Cezar Canducci Dias

    • Marcado como Resposta Wagner W quarta-feira, 13 de novembro de 2013 16:23
    quarta-feira, 13 de novembro de 2013 15:20

Todas as Respostas

  • Bom o Código me aparenta estar certo

    mas, faz o seguinte:

    retire 

    corpo.Clear();
    mailMessagem.Dispose();

    para gente começar a testar o código

    Outra coisa que eu vi e não gosto muito! tira o static isso pode lhe causar problemas! deixa cada usuário cuidar da sua instância ... Então faça classes sem static !!!

    Claro são dicas ai vai de você!!!


    Fulvio Cezar Canducci Dias

    quarta-feira, 13 de novembro de 2013 02:03
  • Olá fulvio, já tinha tentado isto alterei para void e instanciei novamente com new e nada continua demorando 5 segundos para atualizar a pagina e enviar, não esta liberando os objetos, pensei que fosse com o corpo da mensagem ( body ) mas se no metodo assincrono é exatamente pra isto para o usuario não ficar esperando o processamento sinceramente não consigo entender o porque....

    Wagner

    quarta-feira, 13 de novembro de 2013 11:58
  • Desculpa é WebForms ou MVC?

    Fulvio Cezar Canducci Dias

    quarta-feira, 13 de novembro de 2013 12:04
  • WebForms Asp.Net 4.5...

    Wagner

    quarta-feira, 13 de novembro de 2013 12:08
  • Fiz uma classe assim:

    public class Mail
        {
            //string emaildousuario, string emailcomcopia, string mensagem, int assunto, string anexo
            public string EmailUsuario { get; set; }
            public string EmailCopia { get; set; }
            public string Mensagem { get; set; }
            public int Assunto { get; set; }
            public string Anexo { get; set; }
        }
    
        public class MailSend
        {
            private Mail eMail { get; set; }
            public MailSend(Mail eMail)
            {
                this.eMail = eMail;
            }
            public async Task<bool> Send()
            {
                try
                {
                    string Servidor = Constantes.Servidor;
                    string EmailServidor = Constantes.EmailServidor;
                    string SenhaServidor = Constantes.SenhaServidor;
                    int PortaServidor = Constantes.PortaServidor;
                    int DifHoraServer = Constantes.DifHoraServer;
    
                    StringBuilder CorpoMensagem = new StringBuilder();
    
                    CorpoMensagem.Append("Este email foi gerado pelo Sistema, não responda.");
                    CorpoMensagem.Append("</br>----------------------------------------------------");
                    //CorpoMensagem.Append("</br>Usuário: " + (HttpContext.Current != null ? HttpContext.Current.User.Identity.Name.ToUpper() : "Anonimo"));
                    CorpoMensagem.Append("</br>Data: " + DateTime.Now.AddHours(DifHoraServer));
                    CorpoMensagem.Append("</br>Mensagem : " + eMail.Mensagem);
                    CorpoMensagem.Append("</br>Anexo : " + eMail.Anexo);
                    CorpoMensagem.Append("</br>----------------------------------------------------");
                    CorpoMensagem.Append("</br><a href='http://www.meusistema.net.br'>http://www.meusistema.net.br</a>");
                    MailMessage mailMessagem = new MailMessage();
                    mailMessagem.From = new MailAddress(EmailServidor);
                    mailMessagem.To.Add(eMail.EmailUsuario);
                    mailMessagem.CC.Add(eMail.EmailCopia);
                    mailMessagem.Subject = "NOVA OCORRÊNCIA nº " + eMail.Assunto;
                    mailMessagem.IsBodyHtml = true;
                    mailMessagem.Body = CorpoMensagem.ToString();
                    SmtpClient smtp = new SmtpClient();
                    smtp.Port = PortaServidor;
                    smtp.Host = Servidor;
                    smtp.EnableSsl = true;
                    smtp.UseDefaultCredentials = true;
                    smtp.Credentials = new System.Net.NetworkCredential(EmailServidor, SenhaServidor);
                    object userState = mailMessagem;                
                    //smtp.SendAsync(mailMessagem, userState);
                    await smtp.SendMailAsync(mailMessagem);
                    return true;               
                }
                catch
                {
                    return false;
                }
            }
        }


    E montei na página assim:

    public void ButEnviarEmail_Click(object sender, EventArgs e)
    {
    	Task task = new Task(() => Enviar());
    	task.Wait(1000);
    	task.Start();
    }
    public async void Enviar()
    {
    	Mail mail = new Mail();
    	mail.Anexo = "Anexo 1";
    	mail.Assunto = 1;
    	mail.EmailCopia = "dias.fulvio@gmail.com";
    	mail.EmailUsuario = "fulviocanducci@hotmail.com";
    	mail.Mensagem = "teste de e-mail";
    
    	MailSend mailsend = new MailSend(mail);
    	await mailsend.Send();            
    }

    E ASPX assim:

    <%@ Page Language="C#" AutoEventWireup="true" Async="true" CodeBehind="WebForm8.aspx.cs" Inherits="Img.WebForms.WebForm8" %>
    
    <!DOCTYPE html>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
            <asp:ScriptManager ID="ScriptManager1" runat="server" AjaxFrameworkMode="Enabled"></asp:ScriptManager>
        <div>
            <asp:UpdatePanel ID="UpdatePanel1" runat="server" ClientIDMode="Static" UpdateMode="Conditional">
                <ContentTemplate>
                    <asp:Button Text="Enviar E-mail" runat="server" OnClick="ButEnviarEmail_Click" ID="ButEnviarEmail" />
                    <asp:Label Text="" ID="LblMensagemEmail" runat="server" />
                </ContentTemplate>
            </asp:UpdatePanel> 
            <asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1" DisplayAfter="0" ValidateRequestMode="Enabled" ViewStateMode="Enabled" ClientIDMode="Static">
                <ProgressTemplate>Enviando ...</ProgressTemplate>
            </asp:UpdateProgress>       
        </div>
        </form>
    </body>
    </html>


    Desse jeito ele não trava a sua tela funciona perfeitamente!!!

    Obs: na linha dentro da classe terá que mudar somente isso aqui

    CorpoMensagem.Append("</br>Usuário: " + (HttpContext.Current != null ? HttpContext.Current.User.Identity.Name.ToUpper() : "Anonimo"));

    Se vai ter que passar esse valor de User no botão!!! só isso!

    Ai deixo com você! é simples!!!

    Use como exemplo não copia e cola OK!

    Vlw


    Fulvio Cezar Canducci Dias


    quarta-feira, 13 de novembro de 2013 12:56
  • Olá fulvio vou testar e já te respondo... obrigado por enquanto.

    Wagner

    quarta-feira, 13 de novembro de 2013 13:08
  • Olá fulvio, então realmente funcionou o envio... só que no corpo da mensagem que pega o usuário logado no sistema, só passa como "Anonimo" não reconhece quem esta logado, sai e entrei no sistema e não aparece o usuario logado, e outra coisa como eu passo como parametro a string "mensagem" que é associado a um TextBox ele tambem passa nulo, acredito que o refresh na tela apaga o textbox antes de enviar para a classe até ai eu poderia resolver com um select novamente no banco, mas no casso do usuario não entendi...Abç

    Wagner

    quarta-feira, 13 de novembro de 2013 15:17
  • Se vai passar ele antes de gerar o metodo!

    Aqui

    public void ButEnviarEmail_Click(object sender, EventArgs e)
    {
    	Task task = new Task(() => Enviar(HttpContext.Current.User.Identity.Name.ToUpper()));
    	task.Wait(1000);
    	task.Start();
    }
    public async void Enviar(String Usuario)
    {
    	Mail mail = new Mail();
    	mail.Anexo = "Anexo 1";
    	mail.Assunto = 1;
    	mail.EmailCopia = "dias.fulvio@gmail.com";
    	mail.EmailUsuario = "fulviocanducci@hotmail.com";
    	mail.Mensagem = "teste de e-mail";
    
    	MailSend mailsend = new MailSend(mail, Usuario);
    	await mailsend.Send();            
    }

    Percebe os código que eu coloquei no proprio evento que envia!!! Ali meu caro!

    testeeeeeeeeeeeeeeeeeeeeeee


    Fulvio Cezar Canducci Dias

    • Marcado como Resposta Wagner W quarta-feira, 13 de novembro de 2013 16:23
    quarta-feira, 13 de novembro de 2013 15:20
  • Fulvio... obrigado pela paciencia.

    Abç


    Wagner

    quarta-feira, 13 de novembro de 2013 16:23
  • Caro Fulvio, preciso de mais uma ajuda sua em relação ao envio, na minha maquina local funciona perfeitamente mas qdo rodo na hospedagem não envia, entrei em contato com o suporte se poderia haver algum tipo de restrição disseram que não ( não acreditei ) gostaria de saber se vc teve algum problema em hospedagens compartilhadas com o uso de Tasks,  li em alguns fórum que existe um aumento de processamento no servidor será que pode ser uma limitação do hosts... grato.

    Wagner

    segunda-feira, 18 de novembro de 2013 13:08
  • Talvez até o servidor de e-mail esteja bloqueando!

    Eu já tive n problemas com servidores de e-mail compartilhados!!!

    é bem complicado !!!

    coloque try catch para ver se vai te mandar alguma coisa!!!


    Fulvio Cezar Canducci Dias

    segunda-feira, 18 de novembro de 2013 13:23
  • É fulvio foi o que pensei, pois já fiz isto no try/catch e não retorna erro... é infelizmente hospedagem compartilhada sempre vai existir algum tipo de restrição, de qualquer forma obrigado pelo retorno abç...

    Wagner

    segunda-feira, 18 de novembro de 2013 13:37