-
Notifications
You must be signed in to change notification settings - Fork 5k
/
SmtpClientExtensions.cs
74 lines (66 loc) · 3.83 KB
/
SmtpClientExtensions.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
//
using System.Net.Mail;
using System.Threading.Tasks;
namespace System.Net.NetworkInformation
{
/// <summary>Extension methods for working with SmtpClient asynchronously.</summary>
public static class SmtpClientExtensions
{
/// <summary>Sends an e-mail message asynchronously.</summary>
/// <param name="smtpClient">The client.</param>
/// <param name="message">A MailMessage that contains the message to send.</param>
/// <param name="userToken">A user-defined object stored in the resulting Task.</param>
/// <returns>A Task that represents the asynchronous send.</returns>
public static Task SendTask(this SmtpClient smtpClient, MailMessage message, object userToken) =>
SendTaskCore(smtpClient, userToken, tcs => smtpClient.SendAsync(message, tcs));
/// <summary>Sends an e-mail message asynchronously.</summary>
/// <param name="smtpClient">The client.</param>
/// <param name="message">A MailMessage that contains the message to send.</param>
/// <param name="from">A String that contains the address information of the message sender.</param>
/// <param name="recipients">A String that contains the address that the message is sent to.</param>
/// <param name="subject">A String that contains the subject line for the message.</param>
/// <param name="body">A String that contains the message body.</param>
/// <param name="userToken">A user-defined object stored in the resulting Task.</param>
/// <returns>A Task that represents the asynchronous send.</returns>
public static Task SendTask(
this SmtpClient smtpClient, string from, string recipients, string subject, string body, object userToken) =>
SendTaskCore(smtpClient, userToken, tcs => smtpClient.SendAsync(from, recipients, subject, body, tcs));
/// <summary>The core implementation of SendTask.</summary>
/// <param name="smtpClient">The client.</param>
/// <param name="userToken">The user-supplied state.</param>
/// <param name="sendAsync">
/// A delegate that initiates the asynchronous send.
/// The provided TaskCompletionSource must be passed as the user-supplied state to the actual SmtpClient.SendAsync method.
/// </param>
/// <returns></returns>
private static Task SendTaskCore(
SmtpClient smtpClient, object userToken, Action<TaskCompletionSource<object>> 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(nameof(smtpClient));
// Create a TaskCompletionSource to represent the operation
var tcs = new TaskCompletionSource<object>(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;
}
}
}