简体   繁体   English

在.NET Task中发送电子邮件在控制台应用程序中不起作用

[英]Sending email within .NET Task not working in console application

I have the following code below. 我下面有以下代码。 This runs at the end of my console application. 它在控制台应用程序的末尾运行。 I am not receiving emails that go out when it is done within the task, but when I comment out the task factory method it works? 在任务中完成任务后,我没有收到发送出去的电子邮件,但是当我注释掉任务工厂方法时,它行得通吗? The code gets his both times with a breakpoint but the async email flow doesn't ever send out the email. 代码两次都带有断点,但是异步电子邮件流从未发送过电子邮件。 Any reason why? 有什么原因吗?

Task.Factory.StartNew(() =>
{ 
    var smtp = new SmtpClient();
    try
    {
        var toEmails = mailMessage.To.ToList();
        var bccEmails = mailMessage.Bcc.ToList();

        foreach (var email in toEmails)
        {
           mailMessage.To.Clear();
           mailMessage.To.Add(email);
           mailMessage.Bcc.Clear();

           smtp.Send(mailMessage);
        }
     }
     catch (Exception ex)
     {
       Logger.Error(ex);
     }
});

As you say "This runs at the end of my console application" , i am assuming your Main method is terminating before Task.Factory.Startnew has a chance to finish running your code in the background thread. 正如您所说的“这在控制台应用程序的末尾运行” ,我假设您的Main方法在Task.Factory.Startnew有机会在后台线程中完成运行之前终止。

You should either: 您应该:

  1. Run this code synchronously, without starting a new thread (this would be my recommended approach) 同步运行此代码,而无需启动新线程(这是我推荐的方法)
  2. Explicitly wait for the task to finish using Task.Wait while blocking the execution of your Main method, which misses the point of using a ThreadPool thread at all (i wouldn't do this): 明确等待任务使用Task.Wait完成,同时阻止执行Main方法,这Task.Wait错过了使用ThreadPool线程的意义(我不会这样做):

     Task.Factory.StartNew(() => { var smtp = new SmtpClient(); try { var toEmails = mailMessage.To.ToList(); var bccEmails = mailMessage.Bcc.ToList(); foreach (var email in toEmails) { mailMessage.To.Clear(); mailMessage.To.Add(email); mailMessage.Bcc.Clear(); smtp.Send(mailMessage); } } catch (Exception ex) { Logger.Error(ex); } }).Wait(); 

Edit 编辑

I had to add that i would advice you NOT to consume the code from the common library, for a few reasons: 我不得不补充一点,出于以下几个原因,我建议您不要使用公共库中的代码:

  1. It previously returned void and was spinning a redundant ThreadPool thread to do IO based work 它先前返回了void,并且正在旋转一个多余的ThreadPool线程来执行基于IO的工作
  2. This will cause you to have to use Wait on a new thread, you dont need that. 这将导致您不得不在新线程上使用Wait ,而您不需要它。

If you want to consume a true async api (one which doesn't need to use a thread to execute IO bound work) you can use SmtpClient.SendMailAsync and simply await on it: 如果您想使用一个真正的异步api(不需要使用线程来执行IO绑定工作),则可以使用SmtpClient.SendMailAsync并简单地await它:

var smtp = new SmtpClient();
try
{
    var toEmails = mailMessage.To.ToList();
    var bccEmails = mailMessage.Bcc.ToList();

    var taskMails = toEmails.Select(email => 
    {
        var message = new MailMessage
        {
            To = email
        };

        smtp.SendMailAsync(message);
    };

    await Task.WhenAll(taskEmails);
 }
 catch (Exception ex)
 {
   Logger.Error(ex);
 }

I made the return type of Task which gave me the option to wait or not. 我选择了Task的返回类型,这使我可以选择是否等待。

 var task = _emailService.Send(new List<string> { @event.ContactEmail }, subject, body,
                    new List<Attachment>
                        {
                            new Attachment(new MemoryStream(bytes), report.FileName, "application/pdf")
                        });

                if (task != null)
                {
                    task.Wait();
                }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM