All files
[pithos-ms-client] / trunk / Libraries / ParallelExtensionsExtras / Extensions / EAP / SmtpClientExtensions.cs
1 //--------------------------------------------------------------------------
2 // 
3 //  Copyright (c) Microsoft Corporation.  All rights reserved. 
4 // 
5 //  File: SmtpClientExtensions.cs
6 //
7 //--------------------------------------------------------------------------
8
9 using System.Net.Mail;
10 using System.Threading.Tasks;
11
12 namespace System.Net.NetworkInformation
13 {
14     /// <summary>Extension methods for working with SmtpClient asynchronously.</summary>
15     public static class SmtpClientExtensions
16     {
17         /// <summary>Sends an e-mail message asynchronously.</summary>
18         /// <param name="smtpClient">The client.</param>
19         /// <param name="message">A MailMessage that contains the message to send.</param>
20         /// <param name="userToken">A user-defined object stored in the resulting Task.</param>
21         /// <returns>A Task that represents the asynchronous send.</returns>
22         public static Task SendTask(this SmtpClient smtpClient, MailMessage message, object userToken)
23         {
24             return SendTaskCore(smtpClient, userToken, tcs => smtpClient.SendAsync(message, tcs));
25         }
26
27         /// <summary>Sends an e-mail message asynchronously.</summary>
28         /// <param name="smtpClient">The client.</param>
29         /// <param name="message">A MailMessage that contains the message to send.</param>
30         /// <param name="from">A String that contains the address information of the message sender.</param>
31         /// <param name="recipients">A String that contains the address that the message is sent to.</param>
32         /// <param name="subject">A String that contains the subject line for the message.</param>
33         /// <param name="body">A String that contains the message body.</param>
34         /// <param name="userToken">A user-defined object stored in the resulting Task.</param>
35         /// <returns>A Task that represents the asynchronous send.</returns>
36         public static Task SendTask(this SmtpClient smtpClient, string from, string recipients, string subject, string body, object userToken)
37         {
38             return SendTaskCore(smtpClient, userToken, tcs => smtpClient.SendAsync(from, recipients, subject, body, tcs));
39         }
40
41         /// <summary>The core implementation of SendTask.</summary>
42         /// <param name="smtpClient">The client.</param>
43         /// <param name="userToken">The user-supplied state.</param>
44         /// <param name="sendAsync">
45         /// A delegate that initiates the asynchronous send.
46         /// The provided TaskCompletionSource must be passed as the user-supplied state to the actual SmtpClient.SendAsync method.
47         /// </param>
48         /// <returns></returns>
49         private static Task SendTaskCore(SmtpClient smtpClient, object userToken, Action<TaskCompletionSource<object>> sendAsync)
50         {
51             // Validate we're being used with a real smtpClient.  The rest of the arg validation
52             // will happen in the call to sendAsync.
53             if (smtpClient == null) throw new ArgumentNullException("smtpClient");
54
55             // Create a TaskCompletionSource to represent the operation
56              var tcs = new TaskCompletionSource<object>(userToken);
57
58             // Register a handler that will transfer completion results to the TCS Task
59             SendCompletedEventHandler handler = null;
60             handler = (sender, e) => EAPCommon.HandleCompletion(tcs, e, () => null, () => smtpClient.SendCompleted -= handler);
61             smtpClient.SendCompleted += handler;
62
63             // Try to start the async operation.  If starting it fails (due to parameter validation)
64             // unregister the handler before allowing the exception to propagate.
65             try
66             {
67                 sendAsync(tcs);
68             }
69             catch(Exception exc)
70             {
71                 smtpClient.SendCompleted -= handler;
72                 tcs.TrySetException(exc);
73             }
74
75             // Return the task to represent the asynchronous operation
76             return tcs.Task;
77         }
78     }
79 }