![](/img/trans.png)
[英]SmtpClient.SendAsync - How to stop the application exiting before the callback is triggered?
[英]How to safely use SmtpClient.SendAsync in Multithreaded application
在我的應用程序中,我正在使用Dataflow庫中的ActionBlock
通過SmtpClient.SendAsync()
方法發送電子郵件警報,該方法不會阻止調用線程。( ActionBlock
從BufferBlock
獲取數據,並且使用bufferBlock.LinkTo(actionBlock)
塊綁定在一起bufferBlock.LinkTo(actionBlock)
)。 但是,如果.SendAsync()
另一個.SendAsync()
調用,則此方法將引發InvalidOperationException
。
根據MSDN 文檔 ,發送操作完成時會引發public event SendCompletedEventHandler SendCompleted
。
如何確定由ActionBlock
產生的線程(或Tasks
)之間的爭用不會導致引發InvalidOperationException
?
到目前為止,我有一種想法是將圍繞SendAsync()
調用的私有鎖和將分配給SendCompleted
事件的私有函數添加到我的類(發送電子郵件)中。 當線程到達SendAsync()
它獲取鎖,並在引發事件時,私有函數將鎖解鎖,從而允許其他線程獲取鎖並繼續前進。
為每個發送操作創建一個SmtpClient
。 這樣就無需同步任何內容。 只需將其封閉起來即可using
。
您應該只使用SendMailAsync
。 它將從調用SendAsync
開始,並在引發SendCompleted
時完成。
為了確保每次僅發送1條消息,您可以將SemaphoreSlim
設置為1。它基本上是AsyncLock
。
但是,這將限制您的並行性,因為您一次只能執行一個操作。 您可以簡單地使用許多不同的客戶端。 如果每個調用都不是,則使用一些資源池,那么您可以具有並發性,但仍保持每個客戶端線程安全。
var client = _smtpClientPool.Get();
try
{
await client.SendMailAsync(...)
}
finally
{
_smtpClientPool.Put(client);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.