В моем приложении я использую ActionBlock
из библиотеки Dataflow, чтобы отправить оповещения по электронной почте, используя SmtpClient.SendAsync()
метод, который не блокирует вызывающий поток. (ActionBlock
получают свои данные от BufferBlock
, и блоки соединяются вместе, используя bufferBlock.LinkTo(actionBlock)
). Однако этот метод будет вызывать InvalidOperationException
, если выполняется другой вызов .SendAsync()
.Как безопасно использовать SmtpClient.SendAsync в применении многопоточного
В соответствии с MSDN documentation есть public event SendCompletedEventHandler SendCompleted
, который поднимается при завершении операции отправки.
Как я могу убедиться, что гонка между нитями (или Tasks
), порожденная ActionBlock
, не вызовет поворота InvalidOperationException
?
Одна мысль, до сих пор, заключается в том, чтобы добавить к моему классу (который отправляет электронные письма) частный замок вокруг SendAsync()
вызов и приватная функция, которая будет назначена событию SendCompleted
. Когда поток достигает SendAsync()
, он получает блокировку, и когда событие поднимается, частная функция блокирует блокировку, позволяя другим потокам получать блокировку и прогресс.