none
send mail asynchrone RRS feed

  • Question

  • Bonjour , Lors de l'envoi d'un e-mail lourd et que j'ai cliqué dans une autre fenêtre du navigateur, l'envoi de courrier ne fonctionne pas. Je dois donc attendre le chargement du courrier .... J'utilise thred pour éviter ce problème, mais cela ne fonctionne pas.

    aidez-moi s'il vous plaît très urgent.

    protected void SendRejectionsToFiliales()
    {
    RejectManagmentHelper rejectHelper = new RejectManagmentHelper(this._sSqlConnectionString);
    PARAM_AFFILIATE_DAO affiliateDao = new PARAM_AFFILIATE_DAO(this._sSqlConnectionString);

    HiddenField1.Value = "";

    List<ExcelPackage> exelFiles = rejectHelper.CreateLogOfRejectFilesByCompany(HiddenFiledSendRejectMailsLoopCondition.Value);

    ServicePointManager.ServerCertificateValidationCallback =delegate (object s, X509Certificate certificate,X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; };
    CONFIGURATION_DAO configDao = new CONFIGURATION_DAO(this._sSqlConnectionString);
    CONFIGURATION config = configDao.Get("reject_mail_adress");
    string sSender = config.value;
    config = configDao.Get("reject_mail_title");
    string sSubject = config.value;
    config = configDao.Get("reject_mail_content");
    string sMsgText = config.value;
    config = configDao.Get("reject_mail_smtp_host");
    string sSMTPHost = config.value;
    config = configDao.Get("reject_mail_port");
    string sSMTPPort = config.value;
    config = configDao.Get("reject_mail_password");
    string sSenderPassword = config.value;

    foreach (ExcelPackage exelFile in exelFiles)
    {
    FileInfo fo = exelFile.File;
    string sCompanyCode = fo.Name.Substring(4, 3);

    PARAM_AFFILIATE affiliate = affiliateDao.GetByCompanyCode(sCompanyCode);
    string sMailTo = affiliate.affiliateEmailOfReject;
    //HiddenFiledSendRejectMailsLoopCondition.Value = sCompanyCode;
    MailMessage objMailMsg = new MailMessage(sSender, sMailTo);
    objMailMsg.BodyEncoding = Encoding.UTF8;
    objMailMsg.Subject = sSubject;
    objMailMsg.Body = sMsgText;
    objMailMsg.Priority = MailPriority.High;
    objMailMsg.IsBodyHtml = true;
    Attachment at = new Attachment(new MemoryStream(exelFile.GetAsByteArray()), fo.FullName);
    objMailMsg.Attachments.Add(at);

    //prepare to send mail via SMTP transport
    System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient();
    client.Host = sSMTPHost;
    System.Net.NetworkCredential basicauthenticationinfo = new System.Net.NetworkCredential(sSender, sSenderPassword);
    client.Port = int.Parse(sSMTPPort);
    client.EnableSsl = true;
    client.UseDefaultCredentials = false;
    client.Credentials = basicauthenticationinfo;
    client.DeliveryMethod = SmtpDeliveryMethod.Network;
    try
    {
    Thread email = new Thread(delegate ()
    {
    client.Send(objMailMsg);

    });

    email.IsBackground = true;
    email.Start();
    }
    catch (Exception ex)
    {

    }
    }

    HiddenFiledSendRejectMailsLoopCondition.Value = "0";
    }


    vendredi 31 août 2018 18:28

Réponses

  • Bonjour,

    En plus des conseils de Gloops, j'ajouterais un point:

    Vous créez un thread dans une variable locale (email) à votre méthode. Donc quand vous quittez la méthode, votre variable est candidate au garbage collector, et donc au risque de ce faire détruire et le thread killé. Tant que vous ne faites rien il est possible que le GC ne s'exécute pas donc votre variable n'est pas encore libérée, mais lorsque vous quittez votre "page d'envoi" il est possible que le garbage collector s'active et libère votre variable, donc kill votre thread.

    C'est l'une des grandes problématiques du multithread.

    De manière générale aujourd'hui on évite d'utiliser l'objet Thread, on préfère utiliser la TPL (classes Task<> dans l'espace de nom System.Threading.Tasks : https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/task-parallel-library-tpl )

    Sinon dans votre cas, il serait conseillé d'utiliser au moins le ThreadPool pour envoyer votre email, car il gère un pool de threads qui ne sont jamais collectés. Cela devrait vous prémunir du problème que j'évoque.

    Cordialement,


    Yan Grenier

    Merci de bien vouloir "Marquer comme réponse", les réponses qui ont répondues à votre question, et de noter les réponses que vous avez trouvé utiles.

    mercredi 5 septembre 2018 13:14

Toutes les réponses

  • ... (message plus d'actualité) ...


    • Modifié Gloops samedi 1 septembre 2018 09:56
    samedi 1 septembre 2018 00:46
  • ok pas de problème je parle en français 
    samedi 1 septembre 2018 07:37
    • QUAND JE CLIQUE SUR LE BOUTON ENVOYER (MAIL) Je dois pas quitter la page d'envoi depuis 3 menuises pour recevoir un mail.
    • mais je besoins de naviguer sur mon site (quitter la page d'envoi) et recevoir un mail quand même.
      et pour cela je utiliser un thread 

           et voici mon code et je ajouter un thread :

           aidez moi SVP très urgents.

    **************************************************

    protected void SendRejectionsToFiliales()
    {
    RejectManagmentHelper rejectHelper = new RejectManagmentHelper(this._sSqlConnectionString);
    PARAM_AFFILIATE_DAO affiliateDao = new PARAM_AFFILIATE_DAO(this._sSqlConnectionString);

    HiddenField1.Value = "";

    List<ExcelPackage> exelFiles = rejectHelper.CreateLogOfRejectFilesByCompany(HiddenFiledSendRejectMailsLoopCondition.Value);

    ServicePointManager.ServerCertificateValidationCallback =delegate (object s, X509Certificate certificate,X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; };
    CONFIGURATION_DAO configDao = new CONFIGURATION_DAO(this._sSqlConnectionString);
    CONFIGURATION config = configDao.Get("reject_mail_adress");
    string sSender = config.value;
    config = configDao.Get("reject_mail_title");
    string sSubject = config.value;
    config = configDao.Get("reject_mail_content");
    string sMsgText = config.value;
    config = configDao.Get("reject_mail_smtp_host");
    string sSMTPHost = config.value;
    config = configDao.Get("reject_mail_port");
    string sSMTPPort = config.value;
    config = configDao.Get("reject_mail_password");
    string sSenderPassword = config.value;

    foreach (ExcelPackage exelFile in exelFiles)
    {
    FileInfo fo = exelFile.File;
    string sCompanyCode = fo.Name.Substring(4, 3);

    PARAM_AFFILIATE affiliate = affiliateDao.GetByCompanyCode(sCompanyCode);
    string sMailTo = affiliate.affiliateEmailOfReject;
    //HiddenFiledSendRejectMailsLoopCondition.Value = sCompanyCode;
    MailMessage objMailMsg = new MailMessage(sSender, sMailTo);
    objMailMsg.BodyEncoding = Encoding.UTF8;
    objMailMsg.Subject = sSubject;
    objMailMsg.Body = sMsgText;
    objMailMsg.Priority = MailPriority.High;
    objMailMsg.IsBodyHtml = true;
    Attachment at = new Attachment(new MemoryStream(exelFile.GetAsByteArray()), fo.FullName);
    objMailMsg.Attachments.Add(at);

    //prepare to send mail via SMTP transport
    System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient();
    client.Host = sSMTPHost;
    System.Net.NetworkCredential basicauthenticationinfo = new System.Net.NetworkCredential(sSender, sSenderPassword);
    client.Port = int.Parse(sSMTPPort);
    client.EnableSsl = true;
    client.UseDefaultCredentials = false;
    client.Credentials = basicauthenticationinfo;
    client.DeliveryMethod = SmtpDeliveryMethod.Network;
    try
    {
    Thread email = new Thread(delegate ()
    {
    client.Send(objMailMsg);

    });

    email.IsBackground = true;
    email.Start();
    }
    catch (Exception ex)
    {

    }
    }

    HiddenFiledSendRejectMailsLoopCondition.Value = "0";
    }

    samedi 1 septembre 2018 10:42
  • Bonjour,

    C'était une bonne idée l'envoi asynchrone pour qu'on puisse consulter les autres pages pendant l'envoi du mail.

    Bon mais pour finir, multi-threading ou pas, le mail ne part pas, c'est bien ça ?

    Les envois de mails c'est souvent capricieux, et on a du mal à savoir à quel niveau se situe la panne. Ça peut être le serveur SMTP qui ne fonctionne pas, ou qui requiert une authentification (nom d'utilisateur et mot de passe) et celle-ci échoue, ça peut être le serveur à l'arrivée qui ne fonctionne pas ou qui boude le serveur SMTP (ça s'appelle une black-liste), parfois il peut y avoir des soucis entre les deux.

    Hier quelqu'un a eu un souci pour envoyer un mail depuis SQL Server, j'ai suggéré de tester le serveur SMTP à part, ça fait un niveau d'erreur possible en moins.

    Là, pareil, je testerais bien le même paramétrage avec un client de mail, comme Thunderbird par exemple, pour voir ce que ça donne.

    C'est le même principe que lorsqu'on a un problème avec un périphérique : si on peut on teste le périphérique sur une autre machine, et un autre périphérique de même fonction sur la même machine. Ça aide à orienter la suite de l'intervention.



    • Modifié Gloops mercredi 5 septembre 2018 12:42
    mercredi 5 septembre 2018 12:31
  • Bonjour,

    En plus des conseils de Gloops, j'ajouterais un point:

    Vous créez un thread dans une variable locale (email) à votre méthode. Donc quand vous quittez la méthode, votre variable est candidate au garbage collector, et donc au risque de ce faire détruire et le thread killé. Tant que vous ne faites rien il est possible que le GC ne s'exécute pas donc votre variable n'est pas encore libérée, mais lorsque vous quittez votre "page d'envoi" il est possible que le garbage collector s'active et libère votre variable, donc kill votre thread.

    C'est l'une des grandes problématiques du multithread.

    De manière générale aujourd'hui on évite d'utiliser l'objet Thread, on préfère utiliser la TPL (classes Task<> dans l'espace de nom System.Threading.Tasks : https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/task-parallel-library-tpl )

    Sinon dans votre cas, il serait conseillé d'utiliser au moins le ThreadPool pour envoyer votre email, car il gère un pool de threads qui ne sont jamais collectés. Cela devrait vous prémunir du problème que j'évoque.

    Cordialement,


    Yan Grenier

    Merci de bien vouloir "Marquer comme réponse", les réponses qui ont répondues à votre question, et de noter les réponses que vous avez trouvé utiles.

    mercredi 5 septembre 2018 13:14