本文介绍了如何在多线程应用程序中安全使用SmtpClient.SendAsync的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序中,我正在使用Dataflow库中的ActionBlock,通过 SmtpClient.SendAsync() 方法,该方法不会阻止调用线程.(ActionBlock正在从BufferBlock获取数据,并且使用bufferBlock.LinkTo(actionBlock)将块绑定在一起).但是,如果正在进行另一个.SendAsync()调用,则此方法将抛出InvalidOperationException.

根据MSDN 文档,发送操作完成时会出现public event SendCompletedEventHandler SendCompleted.

如何确定由ActionBlock产生的线程(或Tasks)之间的竞争不会导致抛出InvalidOperationException?

到目前为止,我有一个想法是在我的班级(发送电子邮件)中添加SendAsync()调用周围的私有锁和将分配给SendCompleted事件的私有函数.当线程到达SendAsync()时,它将获得锁,并且在引发事件时,私有函数将锁解锁,从而允许其他线程获得锁并继续前进.

解决方案

为每个发送操作创建一个SmtpClient.这样就无需同步任何内容.只需将其包含在using中进行清理即可.

In my application, I am using ActionBlock from Dataflow library, to send out email alerts using SmtpClient.SendAsync() method, which does not block calling thread.(ActionBlock is getting it's data from BufferBlock, and blocks are tied together using bufferBlock.LinkTo(actionBlock)). However, this method will throw InvalidOperationException if another .SendAsync() call is in progress.

According to MSDN documentation, there is public event SendCompletedEventHandler SendCompleted that is raised when send operation completes.

How do I make sure, that race between threads (or Tasks) spawned by ActionBlock will not cause InvalidOperationException to be thrown ?

One thought, I have so far, is to add to my class(that sends out emails) private lock around SendAsync() call and private function that will be assigned to SendCompleted event. When the thread reaches SendAsync() it obtains the lock, and when the event is raised, private function unlocks the lock, allowing other threads to obtain lock, and progress.

解决方案

Create one SmtpClient for each send operation. That way there is no need to synchronize anything. Simply enclose it in using to clean up.

这篇关于如何在多线程应用程序中安全使用SmtpClient.SendAsync的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-23 17:50