Отправлять почту асинхронно C# - PullRequest
0 голосов
/ 16 июня 2020

Prelude : у меня есть метод SendMail, который асинхронно отправляет почту e, и метод Add_Order, который выполняет некоторую операцию, и если переданные параметры соответствуют некоторым требованиям, то из него вызывается функция SendMail для отправки уведомления клиент.

Это проблема : После вызова SendMail Add_Order () продолжает выполняться, пытаясь удалить некоторые файлы, заблокированные другим процессом. На 99% этот процесс представляет собой SendMail (), который еще не завершил свою работу.

Как мне изменить этот код, чтобы решить эту проблему? Я очень ценю, если кто-то может мне помочь. Спасибо за совет

[HttpPost, Route("order_insert")]
    public HttpResponseMessage wsAdd_Order(wsOrdineTulero nOrdine)
    {
        ...

        sendMail(isProd ? rCustomer["MailingList"].ToString() : "f.mail@mail.it", "", ccn, (isProd ? "" : "[TEST] ") + "Tulero - Conferma di spedizione", string.Format(templateMail, mail), true, allegati);

        // This Foreach throw the error because these files are alredy taken by SendMail process 
        foreach (string s in allegati) { File.Delete(s); }
    }




private bool sendMail(string dest, string cc, string ccn, string oggetto, string testo, bool isHtml, string[] allegati)
    {
        try
        {
            SmtpClient smtpClient = new SmtpClient("", 25);

             ...   

            smtpClient.SendCompleted += (s, e) =>
            {
                string sQuery = helper.GetQuery("ADD_MAIL", new string[7] { mail.From.Address, dest, cc, ccn, oggetto, testo.Replace("'", "''"), allegati == null ? "" : string.Join("|", allegati) });
                try { helper.ExecuteSQLNonQuery(sQuery); }
                catch (Exception ex) { helper.NotifyLog(Severity.EXCEPTION_TRACE, ex, "Errore durante la registrazione della mail. Query:|" + sQuery); }
                smtpClient.Dispose();
                mail.Dispose();
            };
            smtpClient.SendAsync(mail, null);

            return true;
        }
        catch (Exception ex) { helper.NotifyLog(Severity.FATAL, ex, string.Format("Failed to send mail|dest: {0}|cc: {1}|ccn: {2}|oggetto: {3}|testo: {4}|isHtml: {5}|allegati: {6}", dest, cc, ccn, oggetto, testo, isHtml, allegati != null ? string.Join("|\\t", allegati) : "")); }
        return false;
    }

1 Ответ

1 голос
/ 16 июня 2020

Вам необходимо использовать шаблон asyn c await. Некоторые методы выполняются асинхронно, как вы сами сказали.

Вы можете заблокировать выполнение кода, используя ключевое слово await перед асинхронным вызовом. Однако, чтобы вы могли использовать ключевое слово await, вам нужно пометить вызывающий его метод async, так как теперь он выполняет что-то асинхронно, то есть сам асинхронно c.

Это должен это сделать:

[HttpPost, Route("order_insert")]
public async Task<HttpResponseMessage> wsAdd_Order(wsOrdineTulero nOrdine)
{
    var success = await sendMail(isProd ? rCustomer["MailingList"].ToString() : "f.mail@mail.it", "", ccn, (isProd ? "" : "[TEST] ") + "Tulero - Conferma di spedizione", string.Format(templateMail, mail), true, allegati);

    // This Foreach throw the error because these files are alredy taken by SendMail process 
    if (success) {
        foreach (string s in allegati) { File.Delete(s); }
    }
}

private async Task<bool> sendMail(string dest, string cc, string ccn, string oggetto, string testo, bool isHtml, string[] allegati)
{
    try
    {
        SmtpClient smtpClient = new SmtpClient("", 25);

        smtpClient.SendCompleted += (s, e) =>
        {
            string sQuery = helper.GetQuery("ADD_MAIL", new string[7] { mail.From.Address, dest, cc, ccn, oggetto, testo.Replace("'", "''"), allegati == null ? "" : string.Join("|", allegati) });
            try { helper.ExecuteSQLNonQuery(sQuery); }
            catch (Exception ex) { helper.NotifyLog(Severity.EXCEPTION_TRACE, ex, "Errore durante la registrazione della mail. Query:|" + sQuery); }
            smtpClient.Dispose();
            mail.Dispose();
        };
        await smtpClient.SendMailAsync(mail);

        return true;
    }
    catch (Exception ex) { helper.NotifyLog(Severity.FATAL, ex, string.Format("Failed to send mail|dest: {0}|cc: {1}|ccn: {2}|oggetto: {3}|testo: {4}|isHtml: {5}|allegati: {6}", dest, cc, ccn, oggetto, testo, isHtml, allegati != null ? string.Join("|\\t", allegati) : "")); }
    return false;
}
...