2013-03-27 59 views
2

CODE: -與任務並行庫發送郵件拋出錯誤

List<Task> tasks = new List<Task>(); 
foreach (var item in arr)//arr contains 1000+ mailids 
      { 
       tasks.Add(Task.Factory.StartNew(() => 
       { 
        using (MailMessage msg = new MailMessage()) 
         { 
          msg=getmsg();//p-shadow code no erorr here 
          SmtpClient smtp = new SmtpClient(); 
          smtp.Host = smtpServer; 
          smtp.Port = smtpPort; 
          smtp.EnableSsl = isSmtpSsl != 0 ? true : false; 
          smtp.Credentials = new NetworkCredential(smtpUName,smtpPass); 
          smtp.Timeout = int.MaxValue; 
          smtp.Send(msg);//---throws error.... 
          //sql code to insert db that mail is send 
         } 
       }, TaskCreationOptions.LongRunning)); 
      } 
      Task.WaitAll(tasks.ToArray<Task>()); 

ERROR- 「發送郵件失敗。」

INTERNAL ERROR-「無法從傳輸連接讀取數據:net_io_connectionclosed。」

+0

難道你打開太多的連接到SMTP服務器,或者打它太快,它的節流嗎?如果每秒鐘執行一次或每五秒執行一次,會發生什麼情況? – 2013-03-27 15:32:13

+0

我不認爲SmtpClient(或服務器)同時支持到同一臺服務器的多個連接。想想你要做的事情:你要求多個'SmtpClient'對象連接到* same *服務器併發送電子郵件。 'SmtpClient'將重新使用連接到同一臺服務器,所以你可能處於競爭狀態。您是否嘗試過使用'SendAsync'而不是使用'Task'? – 2013-03-27 15:56:33

+0

至少,我希望你會想要使用一個'SmtpClient'對象 – 2013-03-27 15:57:26

回答

2

關於「net_io_connectionclosed」異常,請查看此鏈接,因爲它可能會指示您爲何正在關閉連接。這可能是身份驗證問題,防火牆等

Enabling Tracing for System.Net

請找我會在你的情況,而不是產卵1000個任務這是不是很有效的使用下面的代碼。

Sending bulk emails with Tasks Parallel.ForEach

+0

謝謝你的解決方案..我想問你如何決定const int _clientcount = 15? 是clientcount取決於運行硬件或每臺機器的smtp數量受限於.net/iis – 2013-03-28 07:17:00

+0

這僅僅適用於我的環境。取決於每個環境和SMTP服務器的設置。它可能只允許說每個IP 5連接。也許使用配置設置,以便您可以根據環境調整它。 – 2013-03-28 07:31:48

+0

@RyanGunn你設置了SMTPCLients,我有一個需要改變它爲不同的主機。因爲我會使用不同的主機smtp憑證發送電子郵件。所以我必須爲不同的主機啓動15個客戶端。你能給我舉個例子說明我該怎麼做 – coder771 2018-01-19 11:39:19

0

正如吉姆提到的那樣,您可能會遇到節流/拒絕情況。恕我直言,你可能會更成功1)使用單個SmtpClient而不是N個(因此單個客戶端可以在內部序列化爲/如果需要)和2)使用內置的異步調用(SendMailAsync)而不是StartNew並調用同步版本。

喜歡的東西:

var messages = ... // get collection of MailMessage instances 
var smtpClient = new SmtpClient { ... }; // construct a single SmtpClient 
var tasks = messages.Select(smtpClient.SendMailAsync).ToArray(); 
Task.WaitAll(tasks); 

我不知道,如果這是真的什麼幫助,但 - 如果它仍然失敗,你可能只需要進行一個長時間運行的任務發送的電子郵件連續。

+0

如果正在進行電子郵件傳輸,並且您再次調用SendAsync或Send,則將收到InvalidOperationException。取自「http://msdn.microsoft.com/zh-cn/library/system.net.mail.smtpclient.aspx」 – 2013-03-27 19:09:53

+0

@ DNNDev.co.za - 我的代碼段調用的方法是SendMailAsync,而不是Send或SendAsync 。當然,它可能會表現相同的方式,文檔只是沒有更新,但該位文檔並沒有說它會失敗:) – 2013-03-27 23:17:02

+0

道歉,我想念你的代碼在做什麼,並認爲它是調用SendAsync 。 – 2013-03-28 07:32:36