//-------------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. // // File: SmtpClientExtensions.cs // //-------------------------------------------------------------------------- using System.Net.Mail; using System.Threading.Tasks; namespace System.Net.NetworkInformation { /// Extension methods for working with SmtpClient asynchronously. public static class SmtpClientExtensions { /// Sends an e-mail message asynchronously. /// The client. /// A MailMessage that contains the message to send. /// A user-defined object stored in the resulting Task. /// A Task that represents the asynchronous send. public static Task SendTask(this SmtpClient smtpClient, MailMessage message, object userToken) { return SendTaskCore(smtpClient, userToken, tcs => smtpClient.SendAsync(message, tcs)); } /// Sends an e-mail message asynchronously. /// The client. /// A MailMessage that contains the message to send. /// A String that contains the address information of the message sender. /// A String that contains the address that the message is sent to. /// A String that contains the subject line for the message. /// A String that contains the message body. /// A user-defined object stored in the resulting Task. /// A Task that represents the asynchronous send. public static Task SendTask(this SmtpClient smtpClient, string from, string recipients, string subject, string body, object userToken) { return SendTaskCore(smtpClient, userToken, tcs => smtpClient.SendAsync(from, recipients, subject, body, tcs)); } /// The core implementation of SendTask. /// The client. /// The user-supplied state. /// /// A delegate that initiates the asynchronous send. /// The provided TaskCompletionSource must be passed as the user-supplied state to the actual SmtpClient.SendAsync method. /// /// private static Task SendTaskCore(SmtpClient smtpClient, object userToken, Action> sendAsync) { // Validate we're being used with a real smtpClient. The rest of the arg validation // will happen in the call to sendAsync. if (smtpClient == null) throw new ArgumentNullException("smtpClient"); // Create a TaskCompletionSource to represent the operation var tcs = new TaskCompletionSource(userToken); // Register a handler that will transfer completion results to the TCS Task SendCompletedEventHandler handler = null; handler = (sender, e) => EAPCommon.HandleCompletion(tcs, e, () => null, () => smtpClient.SendCompleted -= handler); smtpClient.SendCompleted += handler; // Try to start the async operation. If starting it fails (due to parameter validation) // unregister the handler before allowing the exception to propagate. try { sendAsync(tcs); } catch(Exception exc) { smtpClient.SendCompleted -= handler; tcs.TrySetException(exc); } // Return the task to represent the asynchronous operation return tcs.Task; } } }