Foros del Web » Programando para Internet » ASPX (.net) »

Envío de muchos correos en multitarea (C#)

Estas en el tema de Envío de muchos correos en multitarea (C#) en el foro de ASPX (.net) en Foros del Web. Muy buenas. Cada vez que se inserta una oferta en el portal de empleo en el que estoy trabajando me gustaría que se le enviara ...
  #1 (permalink)  
Antiguo 17/09/2007, 06:22
Avatar de Bravenap  
Fecha de Ingreso: noviembre-2002
Ubicación: Los Arroyos, El Escorial, Madrid
Mensajes: 2.084
Antigüedad: 21 años, 5 meses
Puntos: 4
Envío de muchos correos en multitarea (C#)

Muy buenas. Cada vez que se inserta una oferta en el portal de empleo en el que estoy trabajando me gustaría que se le enviara un aviso por correo electrónico a todos los candidatos apuntados al portal. He pensado en utilizar un hilo multitarea para no sobrecargar el servidor, ya que estamos hablando de unos 1200 candidatos.

No estoy muy familiarizado con C#, el lenguaje en el que estaba originalmente el Portal, pero os muestro lo que he hecho hasta ahora por si hubiera algo que cambiar o mejorar.

Gracias y un saludo.

Código PHP:
        private void btnPublicar_Click(object senderSystem.EventArgs e)
        {
            
//nueva oferta en la base de datos
            
if(Page.IsValid)
            {
                
strCon ConfigurationSettings.AppSettings["constring"];
                
con = new SqlConnection(strCon);
                
string strSql "INSERT INTO ofertas ....";
                
SqlCommand cmd = new SqlCommand(strSql,con);
                
cmd.Parameters.Add("@idEmp",Session["id_empresa"].ToString());
                .....            
                
con.Open();
                try
                {
                    
cmd.ExecuteNonQuery();
                    
//Los datos se han enviado correctamente"
                    
Disable();
                }
                catch (
Exception ex)
                {
                    
//Error al enviar los datos
                
}
                
finally
                
{
                    
con.Close();
                }

                
//mensaje al administrador
                
string message "<body>" +
                    
"<font><b><i>\"" this.txtNomEmp.Text "\"</i></b> " +
                    
"ha publicado una nueva oferta para <b><i>\"" +
                    
this.txtPuesto.Text "\"</i></b>. " +
                    
"<a href='http://miportaldeempleo.ext/admin/Ofertas.aspx'" 
                    
"'>Ver Ofertas</a></font>" +
                    
"</body>";
                
Cartero.Mensaje mail = new Cartero.Mensaje();
                
mail.Hacia "[email protected]";
                
mail.Titulo "Nueva oferta";
                
mail.Cuerpo message;
                try
                {
                    
mail.enviar();
                }
                catch
                {
                    
//no hacemos nada
                
}
                
//Creación de una tarea para el envío del aviso a todos los candidatos.
                
try
                {
                    
Thread tarea = new Thread(new ThreadStart(envioMasivo));
                    
tarea.Priority ThreadPriority.Lowest;
                    
tarea.Start();
                }
                catch
                {}
                
//Fin de tarea.
            
}
        }

        private 
void envioMasivo()
        {
            
string message "<body>" +
                
"<font><b><i>\"" this.txtNomEmp.Text "\"</i></b> " +
                
"ha publicado una nueva oferta para <b><i>\"" +
                
this.txtPuesto.Text "\"</i></b>. " +
                
"<a href='http://miportaldeempleo.ext/'" 
                
"'>Portal de Empleo</a></font>" +
                
"</body>";

            
string strCon ConfigurationSettings.AppSettings["constring"];
            
con = new SqlConnection(strCon);
            
string strSql "SELECT mail FROM candidatos";
            
SqlCommand cmd = new SqlCommand(strSql,con);
            
SqlDataReader r cmd.ExecuteReader();
            while(
r.Read())
            {
                
Cartero.Mensaje mail = new Cartero.Mensaje();
                
mail.Hacia r.GetValue(0).ToString();
                
mail.Titulo "Nueva oferta de empleo!!";
                
mail.Cuerpo message;
                try
                {
                    
mail.enviar();
                }
                catch
                {
                    
//no hacemos nada
                
}
            }
        }
    }

__________________
¡¡NO A LA GUERRA!!
Si ponemos a nuestros mensajes títulos adecuados, la gente se animará más a abrirlos y resultarán más útiles en las busquedas. ¡No a los ayuuudaaa, urgenteee y similares!
  #2 (permalink)  
Antiguo 19/09/2007, 03:38
 
Fecha de Ingreso: febrero-2007
Mensajes: 69
Antigüedad: 17 años, 2 meses
Puntos: 0
Re: Envío de muchos correos en multitarea (C#)

hola, me gustaria saber enviar mails con c# podrias pasarme la clase cartero o indicarme como haces?

saludos
  #3 (permalink)  
Antiguo 19/09/2007, 03:49
Avatar de Bravenap  
Fecha de Ingreso: noviembre-2002
Ubicación: Los Arroyos, El Escorial, Madrid
Mensajes: 2.084
Antigüedad: 21 años, 5 meses
Puntos: 4
Re: Envío de muchos correos en multitarea (C#)

La clase Cartero está escrita en VB, pero vamos, es muy sencillita. En este caso es para correo con autenticación. No obstante te recomiendo que de momento no empieces a utilizar la clase Cartero u otra que te crees tú, si no que utilices el envío normal de mensajes, es decir, escribiendo todo el código para que te vayas familiarizando con él.

Código:
Imports System.Configuration
Imports System.Web.Mail

Public Class Mensaje

    Public Desde As String = ConfigurationSettings.AppSettings("mailCartero")
    Public Hacia As String = ""
    Public Titulo As String = ""
    Public Cuerpo As String = ""
    Public Adjunto As String = ""

    Public Sub enviar()
        Dim mensaje As New MailMessage
        With mensaje
            .Fields("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1
            .Fields("http://schemas.microsoft.com/cdo/configuration/sendusername") = ConfigurationSettings.AppSettings("sendusername")
            .Fields("http://schemas.microsoft.com/cdo/configuration/sendpassword") = ConfigurationSettings.AppSettings("sendpassword")
            .From = Desde
            .To = Hacia
            .Subject = Titulo
            .Body = Cuerpo
            .BodyFormat = MailFormat.Html
            If Adjunto <> "" Then
                .Attachments.Add(Adjunto)
            End If
        End With

        Dim mailSMTP As SmtpMail
        mailSMTP.SmtpServer = ConfigurationSettings.AppSettings("SMTPServer")
        mailSMTP.Send(mensaje)
    End Sub

End Class
Por otro lado, en el tema que nos atañe, había pensado en que a lo mejor es preferible invocar un servicio web para el envío masivo de correos a la lista de distribución. ¿Qué opináis de esto?

Un saludo.
__________________
¡¡NO A LA GUERRA!!
Si ponemos a nuestros mensajes títulos adecuados, la gente se animará más a abrirlos y resultarán más útiles en las busquedas. ¡No a los ayuuudaaa, urgenteee y similares!
  #4 (permalink)  
Antiguo 19/09/2007, 03:53
 
Fecha de Ingreso: febrero-2007
Mensajes: 69
Antigüedad: 17 años, 2 meses
Puntos: 0
Re: Envío de muchos correos en multitarea (C#)

gracias por lo mio
  #5 (permalink)  
Antiguo 19/09/2007, 09:47
Avatar de Bravenap  
Fecha de Ingreso: noviembre-2002
Ubicación: Los Arroyos, El Escorial, Madrid
Mensajes: 2.084
Antigüedad: 21 años, 5 meses
Puntos: 4
Re: Envío de muchos correos en multitarea (C#)

Estaba pensando yo una cosa ....

El hecho de utilizar una hebra o hilo o como se llame hace que se devuelva una respuesta al cliente aunque el proceso no haya terminado, es decir, que el cliente pueda seguir navegando tranquilamente de manera independiente al proceso de envío de los correos electrónicos. Pongamos que si el envío de los correos se demora unos minutos no voy a tener la página en espera del postback hasta que acabe ¿no?
__________________
¡¡NO A LA GUERRA!!
Si ponemos a nuestros mensajes títulos adecuados, la gente se animará más a abrirlos y resultarán más útiles en las busquedas. ¡No a los ayuuudaaa, urgenteee y similares!
  #6 (permalink)  
Antiguo 15/02/2008, 02:27
Avatar de Bravenap  
Fecha de Ingreso: noviembre-2002
Ubicación: Los Arroyos, El Escorial, Madrid
Mensajes: 2.084
Antigüedad: 21 años, 5 meses
Puntos: 4
Re: Envío de muchos correos en multitarea (C#)

Bueno, deseché la cuestión porque no era urgente y sólo por hacer pruebas, pero ahora la verdad es que si me urge. He estado buscando y buscando pero he encontrado respuestas en FDW en los que se indican que al trabajar con un hilo no te devuelve la página al cliente hasta que no termina la tarea.

¿Realmente no existe la manera de ejecutar un método largo y complejo en ASP.Net (con .Net Framework 1.1) sin comprometer la navegación del cliente que lo desencadena?

Un saludo.
__________________
¡¡NO A LA GUERRA!!
Si ponemos a nuestros mensajes títulos adecuados, la gente se animará más a abrirlos y resultarán más útiles en las busquedas. ¡No a los ayuuudaaa, urgenteee y similares!
  #7 (permalink)  
Antiguo 15/02/2008, 03:43
 
Fecha de Ingreso: marzo-2005
Mensajes: 78
Antigüedad: 19 años, 1 mes
Puntos: 0
Re: Envío de muchos correos en multitarea (C#)

si lo haces con threads puedes enviar los correos por un lado y tener el control de usuario por otro lado.

el problema es la capacidad de proceso que tenga tu servidor
  #8 (permalink)  
Antiguo 15/02/2008, 04:09
Avatar de Bravenap  
Fecha de Ingreso: noviembre-2002
Ubicación: Los Arroyos, El Escorial, Madrid
Mensajes: 2.084
Antigüedad: 21 años, 5 meses
Puntos: 4
Re: Envío de muchos correos en multitarea (C#)

Entonces, con el código que puse al principio se tendría que devolver la respuesta al cliente en el momento que finaliza el método btnPublicar_Click, independientemente de que envioMasivo() continúe ejecutándose durante minutos u horas.

Probaré a introducir una pausa en el hilo con un bucle que dure algunos minutillos sin realizar nada en concreto para comprobar el proceso. Ya os contaré.

Un saludo.
__________________
¡¡NO A LA GUERRA!!
Si ponemos a nuestros mensajes títulos adecuados, la gente se animará más a abrirlos y resultarán más útiles en las busquedas. ¡No a los ayuuudaaa, urgenteee y similares!
  #9 (permalink)  
Antiguo 15/02/2008, 04:50
 
Fecha de Ingreso: marzo-2005
Mensajes: 78
Antigüedad: 19 años, 1 mes
Puntos: 0
Re: Envío de muchos correos en multitarea (C#)

exacto!! el hilo trabaja independientemente, lo unico es q gasta recursos de la maquina ()

un poco mas abajo estoy con un tema parecido, te puede interesar el link que deje aunq en este caso te pasara como a mi, esta orientado a winforms pero la estructura de los threads por si tienes problemas esta bien definida.

yo me estoy peleando con el tema de controlar el avance y que el usuario vea el estado del proceso del thread.
  #10 (permalink)  
Antiguo 15/02/2008, 05:02
Avatar de Bravenap  
Fecha de Ingreso: noviembre-2002
Ubicación: Los Arroyos, El Escorial, Madrid
Mensajes: 2.084
Antigüedad: 21 años, 5 meses
Puntos: 4
Re: Envío de muchos correos en multitarea (C#)

Bueno, pues parece que funciona:

Código PHP:
        private void Page_Load(object senderSystem.EventArgs e)
        {
            
Response.Write("· Inicio del proceso " DateTime.Now.ToString() + "<br>");

            try 
            { 
                
Thread tarea = new Thread(new ThreadStart(envioMasivo)); 
                
tarea.Priority ThreadPriority.Lowest
                
tarea.Start(); 
            } 
            catch(
Exception ex)
            {
                
Response.Write("· Error al iniciar la tarea " DateTime.Now.ToString() + "<br>" ex.Message "<br>");
            } 

            
Response.Write("· Fin del proceso " DateTime.Now.ToString() + "<br>");


        }

        private 
void envioMasivo()
        {
            for(
int i 0<= 5i++)
            {
                
Thread.Sleep(5000);
                
Cartero.Mensaje mail = new Cartero.Mensaje();
                
mail.Hacia "[email protected]";
                
mail.Titulo "Inicio iteración "+i+": "+DateTime.Now.ToString();
                
mail.enviar();
            }
        } 
La página de respuesta se ha devuelto inmediatamente:
· Inicio del proceso 15/02/2008 11:46:15
· Fin del proceso 15/02/2008 11:46:15

Y unos segundos después he empezado a recibir los correos a las 11:46:20, 11:46:28, 34, 41, 47 y 54.

Ahora sólo queda hablar con mi provedor para que no haya problemas con los envíos masivos y las "lista negras".

Gracias y un saludo.
__________________
¡¡NO A LA GUERRA!!
Si ponemos a nuestros mensajes títulos adecuados, la gente se animará más a abrirlos y resultarán más útiles en las busquedas. ¡No a los ayuuudaaa, urgenteee y similares!
  #11 (permalink)  
Antiguo 15/02/2008, 06:02
Avatar de Bravenap  
Fecha de Ingreso: noviembre-2002
Ubicación: Los Arroyos, El Escorial, Madrid
Mensajes: 2.084
Antigüedad: 21 años, 5 meses
Puntos: 4
Re: Envío de muchos correos en multitarea (C#)

Pues me permiten un máximo de 200 correos por minuto, de modo que tendré que controlar el tiempo y el número de correos.

Un saludo.
__________________
¡¡NO A LA GUERRA!!
Si ponemos a nuestros mensajes títulos adecuados, la gente se animará más a abrirlos y resultarán más útiles en las busquedas. ¡No a los ayuuudaaa, urgenteee y similares!
  #12 (permalink)  
Antiguo 03/04/2008, 05:18
Avatar de Bravenap  
Fecha de Ingreso: noviembre-2002
Ubicación: Los Arroyos, El Escorial, Madrid
Mensajes: 2.084
Antigüedad: 21 años, 5 meses
Puntos: 4
Re: Envío de muchos correos en multitarea (C#)

He probado con este código pero ningún candidato recibe los avisos:

Código PHP:
        private void envioMasivo()
        {
            
string message "<body>" +
                
"<font><b><i>\"" this.txtNomEmp.Text "\"</i></b> " +
                
"ofrece el puesto de <b><i>\"" +
                
this.txtPuesto.Text "\"</i></b><br>. " +
                
"<a href='http://miportaldeempleo.com/Oferta.aspx?id_oferta=" id_oferta "'" 
                
"'>Ver oferta/a></font>" +
                
"</body>";

            
string strCon ConfigurationSettings.AppSettings["constring"];
            
con = new SqlConnection(strCon);
            
string strSql "SELECT mail FROM candidatos";
            
SqlCommand cmd = new SqlCommand(strSql,con);
            
SqlDataReader r cmd.ExecuteReader();

            
DateTime inicio = new DateTime();
            
inicio DateTime.Now;
            
TimeSpan resta = new TimeSpan();
            
int numEnvios 0;
            
int numMaxEnvios 150;
            while(
r.Read())
            {
                
Cartero.Mensaje mail = new Cartero.Mensaje();
                
mail.Hacia r.GetValue(0).ToString();
                
mail.Titulo "¡¡Nueva oferta!!";
                
mail.Cuerpo message;
                    
                try
                {
                    
mail.enviar();
                }
                catch {} 
//No hacemos nada si falla
                
resta DateTime.Now.Subtract(inicio);
                
numEnvios += 1;                
                
                if(
numEnvios numMaxEnvios)
                {        
                    while(
resta.Seconds 60)
                    {
                        
Thread.Sleep(1000);
                        
resta DateTime.Now.Subtract(inicio);
                    }
                
numEnvios 0;
                
inicio DateTime.Now;
                }
            }
            
r.Close();
            
cmd.Dispose();
        } 
¿Veis algún fallo?
__________________
¡¡NO A LA GUERRA!!
Si ponemos a nuestros mensajes títulos adecuados, la gente se animará más a abrirlos y resultarán más útiles en las busquedas. ¡No a los ayuuudaaa, urgenteee y similares!
  #13 (permalink)  
Antiguo 03/04/2008, 05:57
Avatar de Bravenap  
Fecha de Ingreso: noviembre-2002
Ubicación: Los Arroyos, El Escorial, Madrid
Mensajes: 2.084
Antigüedad: 21 años, 5 meses
Puntos: 4
Re: Envío de muchos correos en multitarea (C#)

Yo me lo guiso, yo me lo como. Faltaba algo importante:

con.Open();


Como parece que marcha ahora a esperar a que no me baneen el servidor de correo.

Un saludo.
__________________
¡¡NO A LA GUERRA!!
Si ponemos a nuestros mensajes títulos adecuados, la gente se animará más a abrirlos y resultarán más útiles en las busquedas. ¡No a los ayuuudaaa, urgenteee y similares!
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 18:21.