2008-12-23 172 views
21

我正在嘗試在.NET中使用SmtpClient編寫通知服務(用於完全合法的非垃圾郵件目的)。最初,我只是通過每封郵件循環發送,但這很慢,我想提高速度。所以,我切換到使用「SendAsync」,但現在收到以下錯誤的第二個電話:爲什麼只能調用SmtpClient.SendAsync一次?

An asynchronous call is already in progress. 

我讀這意味着MS癱瘓System.Net.Mail防止羣發郵件。它是否正確?如果是這樣,有沒有更好的方式在.NET中做到這一點,並仍然能夠記錄每封電子郵件的結果(這對我們的客戶來說很重要)。如果不是,爲什麼SendAsync只能被調用一次?

回答

35

按照documentation

調用SendAsync後,必須試圖發送 使用發送或 SendAsync其他電子郵件消息之前等待 的E-mail發送到 完整。

因此,要同時發送多個郵件,您需要多個SmtpClient實例。

+0

是否有人已經實現了這種機制一次發送多個電子郵件?在smtp客戶端類的頂部?聽起來像是很多人遇到的問題......有點奇怪,沒有人爲它創建過一些框架。 – 2011-10-26 15:54:21

+3

@ItayLevin我沒有看到需要嘗試重用SmtpClient實例。 Darin熟練地解釋了這一點,爲什麼不只是爲每個電子郵件發送嘗試分配每個實例。 – Roman 2012-04-23 17:54:53

+0

這是關於該主題的[良好帖子](http://www.codefrenzy.net/2012/01/30/how-asynchronous-is-smtpclient-sendasync/)。 – 2016-12-12 16:31:31

3

很顯然,這不是企圖阻止羣發郵件。

原因是SmtpClient類不是線程安全的。如果要同時發送多個電子郵件,則必須生成一些工作線程(在.NET Framework中有幾種方法可以實現這一點),並在每個線程中創建單獨的SmtpClient實例。

1

每個SMTP客戶端一次只能發送一個。如果您希望發送多個發送呼叫,請創建多個SMTP客戶端。

HTH,

科爾比非洲

3

我想你誤會XXXAsync類的方法。這些異步調用的目的是讓程序繼續運行,而不需要方法來完成處理並首先返回。然後,您可以通過訂閱對象的XXXReceived事件來處理結果。

要同時發送多個郵件,您可以考慮使用更多Thread s。

2

正如其他人在這裏注意到的,您一次只能發送一封電子郵件,但發送第一封郵件的方式是處理SmtpClient類的.SendCompleted事件,然後繼續下一封電子郵件併發送。

如果您想同時發送多封電子郵件,正如其他人所說的那樣,請使用多個SmtpClient對象。

6

您可能能夠使用以下命令:

ThreadPool.QueueUserWorkItem(state => client.Send(msg)); 

這應該允許進行排隊和發送,線程郵件變得可用。

相關問題