【问题标题】:Task.Factory.StartNew Run Task in parallelTask.Factory.StartNew 并行运行任务
【发布时间】:2014-03-04 14:47:08
【问题描述】:

我是 C# 中使用线程的新手,即使我一直在阅读漏洞日,我也无法解决这个问题:

我有一个使用框架 4.5 发送电子邮件的控制台应用程序,问题是即使我使用的是 Task.Factory.StartNew,该应用程序似乎是按顺序运行线程而不是并行运行。

谁能给我一些建议?

注意: queuedEmails 包含最多 70 个电子邮件列表

代码:

public void Send()
{
    IList<Task> tasks = new List<Task>();
    List<string> logLines = new List<string>();

    foreach (EmailEnt emailEnt in queuedEmails)
    {
        string subject = "I'm the subject";
        string cuerpo_email = "I'm the email body";

        tasks.Add(Task.Factory.StartNew(() =>
        {
                DownloadHtml("http://www.google.com");
                Console.Out.WriteLine("done"+DateTime.Now.TimeOfDay);
        }));
    }
    Task.WaitAll(tasks.ToArray());
}

  public static string DownloadHtml(string Url)
    {
        // Open a connection
        HttpWebRequest WebRequestObject = (HttpWebRequest)HttpWebRequest.Create(Url);

        // You can also specify additional header values like 
        // the user agent or the referer:

        WebRequestObject.UserAgent = ".NET Framework/2.0";
        WebRequestObject.Referer = "http://www.example.com/";

        // Request response:
        WebResponse Response = WebRequestObject.GetResponse();

        // Open data stream:
        System.IO.Stream WebStream = Response.GetResponseStream();

        // Create reader object:
        System.IO.StreamReader Reader = new System.IO.StreamReader(WebStream);

        // Read the entire stream content:
        string PageContent = Reader.ReadToEnd();

        // Cleanup
        Reader.Close();
        WebStream.Close();
        Response.Close();

        return PageContent;
    }

【问题讨论】:

  • 您正在重用一个名为 email 的字段。那是什么类型的?
  • 是我自己的班级来发送电子邮件
  • 那么把代码贴出来才有意义,否则很难给你可靠的建议!
  • 我已经更新了代码

标签: c# multithreading task


【解决方案1】:

De SendMailMessage 方法不能异步调用。因此准备您的邮件将并行完成,但由于发送是按顺序完成的,您的电子邮件将被逐一发送。

http://msdn.microsoft.com/en-us/library/swas0fwc%28v=vs.110%29.aspx

【讨论】:

  • 该方法调用 AWS SES Web 服务。它不调用 SMTP 服务器
  • 无论您调用什么服务器,.NET 都会阻止 SendMailMessage 调用上的并行请求。
【解决方案2】:

如果您的 SendMailMessage 方法使用 SmtpClient.Send 方法,则在 MSDN 文档 (http://msdn.microsoft.com/en-us/library/swas0fwc(v=vs.110).aspx) 中显示:

此方法在电子邮件传输时阻塞。

还有:

如果有消息异步发送,则不能调用该方法。

因此,如果您想并行发送,您似乎必须使用另一种方法......但是同步发送应该会带来任何问题,因为好的 SMTP 服务器可以快速处理传出消息(并且通常只是将它们排队)。

【讨论】:

  • 我没有使用 SMTP 服务器,它是 AWS amazon SES Web 服务。
  • 看,这就是为什么显示您希望人们建议的代码很方便的原因。
【解决方案3】:

您的电子邮件提供商或您与电子邮件提供商的网络连接可能无法支持大量并发连接。只允许几个并发请求,甚至可能只允许一个并发请求,这并不异常。

如果您做的不是发送电子邮件,您可能会看到一些并行化,但在这种情况下,您的请求将进一步同步。

【讨论】:

  • 是的,亚马逊 SES 确实如此。在 sendEmails 方法中,我编写了一个操作循环(而不是调用 Web 服务)以消除问题可能是网络问题,并且发生的情况相同。它们按顺序运行
  • @RobertoZamora 这也是一项与网络相关的任务,并且很可能受到同样的限制。
  • 我用 while(10000000){double a = 12.321321*123.23546} 替换了对 Web 服务的调用,并且发生了同样的行为。
  • @RobertoZamora 您如何观察到这些操作没有并行化的事实?特别是在您的最后一个示例中,没有观察到任何副作用。
  • 循环结束有一个 Console.Out.WriteLine("DONE");
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-23
  • 2020-06-21
  • 1970-01-01
  • 2020-01-02
  • 2016-02-28
  • 1970-01-01
相关资源
最近更新 更多