-
Notifications
You must be signed in to change notification settings - Fork 5k
Replace ATP pattern with async/await in SmtpClient (part 2) #115722
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR replaces the ATP pattern with first‑class async/await implementations for SmtpClient and related components, streamlining asynchronous mail sending and connection handling.
- Converts legacy Begin/End method patterns to async/await implementations.
- Updates tests and project file references to use the common ReadWriteAdapter implementation.
- Removes redundant legacy code in System.Net.Mail and System.Net.Security.
Reviewed Changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated no comments.
Show a summary per file
File | Description |
---|---|
System.Net.Security.Unit.Tests.csproj | Removed legacy ReadWriteAdapter reference and added the Common version. |
System.Net.Security (ReadWriteAdapter.cs) | Removed the legacy ReadWriteAdapter implementation. |
System.Net.Mail.Unit.Tests.csproj | Updated test project references to use the Common ReadWriteAdapter. |
SmtpClientTest.cs | Added a test to validate SendAsync cancellation behavior. |
SmtpTransport.cs | Refactored connection and mail sending methods to async/await and removed legacy synchronous methods. |
SmtpReplyReaderFactory.cs / SmtpReplyReader.cs | Removed synchronous wrappers in favor of fully asynchronous implementations. |
SmtpCommands.cs | Eliminated obsolete command wrappers, relying solely on async patterns. |
MailMessage.cs | Removed synchronous send wrappers in favor of async implementations. |
System.Net.Mail.csproj | Updated file references and removed legacy items. |
Common/ReadWriteAdapter.cs | Moved the ReadWriteAdapter into the shared Common folder with an updated namespace. |
Comments suppressed due to low confidence (1)
src/libraries/System.Net/Mail/SmtpTransport.cs:151
- [nitpick] Consider using a dedicated private lock object instead of locking on 'this' to improve encapsulation and reduce potential deadlock risks.
lock (this)
Tagging subscribers to this area: @dotnet/ncl |
Nice diff! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice cleanup
src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpClient.cs
Outdated
Show resolved
Hide resolved
CancellationTokenSource currentCts = Interlocked.Exchange(ref _pendingSendCts, new CancellationTokenSource()); | ||
|
||
currentCts.Cancel(); | ||
currentCts.Dispose(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it OK to not call Abort() here? It was called in previous implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The abort is called by the SendAsyncInternal when processing any fatal exception.
This PR removes the rest of the ATP pattern usage in System.Net.Mail.
Formerly, the newer
SendMailAsync
methods were implemented as a wrapper over (void returning)SendAsync
and listening for completion viaSendCompleted
async event. This PR reverses that order, so thatSendMailAsync
is implemented as first class method, andSendAsync
is implemented as a wrapper overSendMailAsync
for compatibility.The exception handling is a bit complicated to preserve outward behavior with regards to wrapping the exception in SmtpException.
Fixes #115070