【问题标题】:Send Multi-Threading SMTP emails发送多线程 SMTP 电子邮件
【发布时间】:2015-01-18 13:53:05
【问题描述】:

我开发了一个主要使用 SMTP 发送电子邮件的应用程序。

MailMessage mail = new MailMessage();
mail.From = new MailAddress("from", "to");
mail.Subject = "subject";
mail.Body = "body";

SmtpClient client = new SmtpClient("my domain");
client.Credentials = new NetworkCredential(from, "MyPass");
client.Send(mail);

这很好,但现在我想同时发送多条消息而无需等待,所以我将所有消息放在一个列表中:

List<MailMessage> emails = new List<MailMessage>();
emails.Add(new MailMessage (...));
emails.Add(new MailMessage (...));
emails.Add(new MailMessage (...));
...

我想为每封电子邮件打开新的Thread

// Generate and execute all mails concurrently
var emailTasks = emails.Select(msg =>
                 {
                     client = new SmtpClient();
                     return client.SendAsync(msg);
                 });

// Asynchronously wait for all of them to complete.
await Task.WhenAll(emailTasks);

得到了这个错误:

没有SendMailAsync,最后一行代码也报错: 'await' 运算符只能在异步方法中使用。考虑 用 'async' 修饰符标记这个方法并改变它的返回值 键入“任务”

【问题讨论】:

    标签: c# .net multithreading smtp


    【解决方案1】:

    发生错误是因为您在同一个 SmtpClient 实例上进行了多次 SMTP 调用,该实例被所有线程捕获。

    您可以在SmtpClient.Send的源代码中看到它(为简洁起见):

    try 
    {
        // If there is already an ongoing SMTP request
        if (InCall)
        {
            throw new InvalidOperationException(SR.GetString(SR.net_inasync));
        }
    }
    

    通常,您不需要使用任何线程来执行 I/O 绑定操作,因为它们本质上是异步的。

    相反,您可以使用 async-await 来利用异步 API:

    // Generate and execute all mails concurrently
    var emailTasks = emails.Select(msg => 
                     {
                        var client = new SmtpClient();
                        return client.SendMailAsync(msg));
                     });
    
    // Asynchronously wait for all of them to complete.
    await Task.WhenAll(emailTasks);
    

    【讨论】:

    • 我需要把这段代码放在哪里?和 SendAsync 期望更多的参数(对象 userToken) - 我应该在这里放什么?
    • SmtpClient.SendMailAsync,不是SendAsync
    • 没有SendMailAsync,最后一行代码也报错:'await'操作符只能在异步方法中使用。考虑使用 'async' 修饰符标记此方法并将其返回类型更改为 'Task'
    • @Maggy 请使用完整的方法执行编辑您的问题,以便我可以正确回答
    猜你喜欢
    • 2012-03-21
    • 1970-01-01
    • 2011-07-30
    • 2019-06-16
    • 2017-02-11
    • 1970-01-01
    • 1970-01-01
    • 2016-04-17
    • 2017-02-09
    相关资源
    最近更新 更多